Typing State
In this page:
Basic useState Typing
Basic useState typing is inferred automatically from the initial value you pass in, so useState(0) already gives you a state variable typed as number without needing any manual annotation.
Example: Basic useState Typing
import React, { useState } from "react";
function Counter(): React.JSX.Element {
const [count, setCount] = useState(0);
return <p>{count}</p>;
}
export default Counter;
Explicit State Types
An explicit type argument to useState<T>() is needed when the initial value doesn't fully describe the type you actually want — for example when the state can later hold one of several different shapes.
Example: Explicit State Types
import React, { useState } from "react";
type Status = "idle" | "loading" | "done";
function Loader(): React.JSX.Element {
const [status, setStatus] = useState<Status>("idle");
return <p>{status}</p>;
}
export default Loader;
Nullable State
Nullable state is typed explicitly as useState<User | null>(null), which forces every place that reads the state to first check it isn't null before accessing a property on the expected object.
Example: Nullable State
import React, { useState } from "react";
interface User {
name: string;
}
function Profile(): React.JSX.Element {
const [user, setUser] = useState<User | null>(null);
return <p>{user ? user.name : "No user"}</p>;
}
export default Profile;
Array State
Array state benefits from an explicit type argument like useState<Item[]>([]), since an empty array alone gives TypeScript no information about what type of items the array is meant to eventually hold.
Example: Array State
import React, { useState } from "react";
interface Item {
id: number;
label: string;
}
function List(): React.JSX.Element {
const [items, setItems] = useState<Item[]>([]);
return <p>{items.length} items</p>;
}
export default List;
State with Functional Updates
Functional updates — setState(prev => ...) — automatically type the prev parameter as the state's current type, letting you safely compute a new value from the previous one without re-declaring the type by hand.
Example: State with Functional Updates
import React, { useState } from "react";
function Counter(): React.JSX.Element {
const [count, setCount] = useState(0);
const increment = () => setCount((prev) => prev + 1);
return <button onClick={increment}>{count}</button>;
}
export default Counter;
Chapter Quiz — Complete all 8 topics to unlock
0/8 topics done
Complete these topics first: