useState, useEffect, useRef, and useContext - Textnotes

useState, useEffect, useRef, and useContext


Learn how to use React hooks with TypeScript for type-safe state management, side effects, references, and context. This module explains typing useState, useEffect, useRef, and useContext with practical examples.

1. useState Typing

The useState hook can be typed using generics to ensure the state value is type-safe.

Basic Example


import { useState } from "react";

const Counter: React.FC = () => {
const [count, setCount] = useState<number>(0);

return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};

Complex State


interface User {
id: number;
name: string;
}

const [user, setUser] = useState<User | null>(null);

Typing useState prevents invalid updates and improves code safety.

2. useEffect Typing

useEffect runs side effects, and its typing helps ensure the correct dependencies are handled.

Basic Example


import { useEffect, useState } from "react";

const Timer: React.FC = () => {
const [seconds, setSeconds] = useState<number>(0);

useEffect(() => {
const interval = setInterval(() => {
setSeconds(prev => prev + 1);
}, 1000);

return () => clearInterval(interval); // Cleanup
}, []);

return <div>Seconds: {seconds}</div>;
};

Example with Props


interface Props {
initialCount: number;
}

useEffect(() => {
setCount(initialCount);
}, [initialCount]);

Typing ensures proper usage of state and dependencies in useEffect.

3. useRef Typing

useRef can hold references to DOM elements or mutable values and requires typing for safety.

DOM Element Reference


import { useRef } from "react";

const InputFocus: React.FC = () => {
const inputRef = useRef<HTMLInputElement>(null);

const focusInput = () => {
inputRef.current?.focus();
};

return <input ref={inputRef} placeholder="Type here" />;
};

Mutable Value Reference


const countRef = useRef<number>(0);
countRef.current += 1;

Typing useRef ensures safe access to .current.

4. useContext Typing

useContext provides type-safe access to React context values.

Example


import { createContext, useContext } from "react";

interface ThemeContextType {
darkMode: boolean;
toggle: () => void;
}

const ThemeContext = createContext<ThemeContextType | undefined>(undefined);

const Component: React.FC = () => {
const theme = useContext(ThemeContext);

if (!theme) throw new Error("ThemeContext not provided");

return (
<div style={{ background: theme.darkMode ? "black" : "white" }}>
<button onClick={theme.toggle}>Toggle Theme</button>
</div>
);
};

Typing useContext ensures proper usage of context values and prevents runtime errors.

Conclusion

Using React hooks with TypeScript provides type safety for state, side effects, references, and context. Proper typing of useState, useEffect, useRef, and useContext improves maintainability, reduces runtime errors, and enables scalable React applications.