█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/TypeScript/TypeScript with React
45 minIntermediate

TypeScript with React

After this lesson, you will be able to: Type React: props, hooks, events, context, refs.

TS + React is the modern frontend default. This lesson covers the patterns that come up daily.

Prerequisites:Advanced Types

Typing component props

Function components are simplest.

html
import { type ReactNode } from "react";
type ButtonProps = {
children: ReactNode;
variant?: "primary" | "secondary";
onClick?: (e: React.MouseEvent<HTMLButtonElement>) => void;
disabled?: boolean;
};
export function Button({ children, variant = "primary", onClick, disabled }: ButtonProps) {
return (
<button onClick={onClick} disabled={disabled} className={variant}>
{children}
</button>
);
}
// Use ComponentProps for forwarding
type InputProps = React.ComponentProps<"input"> & { label: string };

Typing hooks

useState + useReducer + useRef + useContext.

html
import { useState, useReducer, useRef, useContext, createContext } from "react";
// useState, explicit when initial is null
const [user, setUser] = useState<User | null>(null);
const [count, setCount] = useState(0); // inferred
// useReducer
type Action = { type: "inc" } | { type: "set"; value: number };
function reducer(state: number, a: Action): number {
switch (a.type) {
case "inc": return state + 1;
case "set": return a.value;
}
}
const [n, dispatch] = useReducer(reducer, 0);
// useRef
const inputRef = useRef<HTMLInputElement>(null);
// useContext
const UserContext = createContext<User | null>(null);
const user2 = useContext(UserContext); // User | null

Custom hooks

Same patterns; type return values explicitly.

tsx
function useToggle(initial = false): [boolean, () => void] {
const [value, setValue] = useState(initial);
const toggle = useCallback(() => setValue((v) => !v), []);
return [value, toggle];
}
function useFetch<T>(url: string): { data: T | null; loading: boolean; error: Error | null } {
// ... implementation
return { data, loading, error };
}
// Type inferred at call site:
const { data } = useFetch<User>("/api/me"); // data: User | null

Common mistakes only experienced React+TS devs avoid

Using FC<Props> (Function Component). Older pattern; just type the function directly. Forgetting `key` types in lists. Typing event handlers as `any`. Use React.MouseEvent / React.ChangeEvent. useRef<HTMLInputElement>() instead of useRef<HTMLInputElement>(null). null initial is required for DOM refs.

Quick Check

Why type useState as `useState<User | null>(null)` instead of `useState(null)`?

Pick the senior answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←Advanced Types
Back to TypeScript
TypeScript with Node.js + Express/Fastify→