All skills
asyrafhussin avatar

/typescript-react-patterns

@e60e907

TypeScript best practices for React development. Use when writing typed React components, hooks, events, refs, or generic components. Triggers on tasks involving TypeScript errors, type definitions, props typing, or type-safe React patterns.

Use this Skill: https://skilld.dev/gh/asyrafhussin/agent-skills/typescript-react-patterns

This session only. Nothing lands on disk.

rulesref-dom-elements.md

≈910 tokens on demand. Your agent reads this file only when SKILL.md points to it.

useRef for DOM Elements

Impact: HIGH (prevents null access crashes and enables precise DOM typing)

When using useRef for DOM elements, pass null as the initial value and use the most specific HTML element type. This returns a RefObject with a read-only .current that is null until React attaches the element.

Incorrect

// ❌ Bad
function BadForm() {
  // Missing type parameter — .current is undefined, not null
  const inputRef = useRef();

  // Too generic — loses element-specific properties like .value, .focus()
  const anotherRef = useRef<HTMLElement>(null);

  // Missing null initial value — returns MutableRefObject, not RefObject
  const divRef = useRef<HTMLDivElement>();

  const handleClick = () => {
    // No null check — crashes if element isn't mounted
    console.log(inputRef.current.value);
    inputRef.current.focus();
  };

  return (
    <div ref={divRef}>
      <input ref={inputRef} />
      <button onClick={handleClick}>Focus</button>
    </div>
  );
}

Problems:

  • useRef() without a type defaults to undefined, not null — won't match React's ref assignment
  • HTMLElement is too generic and lacks element-specific properties like value on inputs
  • Missing null initial value creates a MutableRefObject instead of RefObject
  • No null check before accessing .current causes runtime crashes

Correct

// ✅ Good
function SearchForm() {
  // Specific element types — pass null to get RefObject
  const inputRef = useRef<HTMLInputElement>(null);
  const formRef = useRef<HTMLFormElement>(null);
  const canvasRef = useRef<HTMLCanvasElement>(null);

  useEffect(() => {
    // Always check for null before accessing .current
    if (inputRef.current) {
      inputRef.current.focus(); // .focus() is available on HTMLInputElement
    }
  }, []);

  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (inputRef.current) {
      console.log(inputRef.current.value); // .value is typed
      inputRef.current.select(); // .select() is typed
    }
  };

  const drawCanvas = () => {
    if (canvasRef.current) {
      // .getContext() is available because we used HTMLCanvasElement
      const ctx = canvasRef.current.getContext("2d");
      if (ctx) {
        ctx.fillRect(0, 0, 100, 100);
      }
    }
  };

  return (
    <form ref={formRef} onSubmit={handleSubmit}>
      <input ref={inputRef} type="search" />
      <canvas ref={canvasRef} />
      <button type="submit">Search</button>
    </form>
  );
}

// Using a ref for a video element
function VideoPlayer({ src }: { src: string }) {
  const videoRef = useRef<HTMLVideoElement>(null);

  const play = () => videoRef.current?.play();
  const pause = () => videoRef.current?.pause();

  return (
    <div>
      <video ref={videoRef} src={src} />
      <button onClick={play}>Play</button>
      <button onClick={pause}>Pause</button>
    </div>
  );
}

Benefits:

  • useRef<HTMLInputElement>(null) returns RefObject<HTMLInputElement> with read-only .current
  • Element-specific methods and properties (value, focus, select, getContext) are fully typed
  • Null checks prevent runtime crashes when the element isn't mounted
  • Optional chaining (ref.current?.method()) provides concise null-safe access

Reference: React TypeScript Cheatsheet — useRef

Source: SKILL.md on GitHub

No alerts16d5 checks · Risk SAFE
  • Gen Agent Trust Hub16d

    The skill contains educational reference material and code documentation for TypeScript React development patterns. No security risks or malicious vectors were detected.

  • Socket16d

    No alerts

  • Snyk16d

    Risk: LOW · No issues

  • Runlayer6mo

    30 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e60e907. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub last month.

Steadyupdated 7 months ago
metadata
{
  "author": "agent-skills",
  "version": "2.0.0"
}

README badge

README badge for asyrafhussin/agent-skills/typescript-react-patterns