How to Use React UseState Hook in TypeScript
-
the React
useState
Hook Definition -
Use Primitive Types With React
useState
Hook in TypeScript - Use User-Defined Interfaces to Store States in TypeScript
-
Use Arrays in
useState
Hook in TypeScript
This article will demonstrate using the React useState
hook in TypeScript.
the React useState
Hook Definition
The React useState
hook plays an important part when using functional components, from storing temporary data to receiving data from an API call. With the introduction of TypeScript, developer experience has increased manifold.
TypeScript has support for adding types to React useState
hook. This is advantageous as TypeScript can infer the types during setting the values and even detect errors in types.
This can be mitigated much earlier, leading to safe deployment.
TypeScript has a generic definition for React useState
according to the TypeScript React documentations.
function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
Here, S
is a generic type. It accepts an initial state, and the hook can accept the state indicated by S
and a setState
function of type Dispatch<SetStateAction<S>>
.
An easy way to know the inferred type of the setState
function is to hover over the variable in any proper IDE or text editor like VSCode.
Use Primitive Types With React useState
Hook in TypeScript
The useState
hook can set primitive types in the application state. The primitive types include number
, string
, and boolean
.
Here is an example of how useState
can be used for primitive types in TypeScript.
const InfoComponent = () => {
const [name, setName] = React.useState<string>("");
const [age, setAge] = React.useState<number>(0);
const [isMarried, setIsMarried] = React.useState<boolean>(false);
React.useEffect(() => {
setName("Geralt");
setAge(95);
setIsMarried(false);
}, []);
return (
<>
<div>Witcher name : {name}</div>
<div>Age : {age}</div>
<div>Married : {isMarried ? 'Yes' : 'No'}</div>
</>
)
}
Thus the useState
hook has been used for storing the primitive types which are being set in a useEffect
hook which gets triggered once when the component is mounted.
Use User-Defined Interfaces to Store States in TypeScript
Even user-defined interfaces can be used as a type for the useState
hook. The code segment used in the previous section can be modified to store the information in an interface so that the code becomes more organized.
interface IUser {
name : string ;
age : number ;
isMarried : boolean ;
}
const InfoComponent = () => {
const [ state, setState ] = React.useState<IUser>({
name : "",
age : 0,
isMarried : false
});
React.useEffect(() => {
setState({
name : "Geralt",
age : 95,
isMarried : false
});
}, []);
return (
<>
<div>Witcher name : {state.name}</div>
<div>Age : {state.age}</div>
<div>Married : {state.isMarried ? 'Yes' : 'No'}</div>
</>
)
}
For setting optional fields in the setState
function, the as
keyword can be used for type assertion. We must override the initial state with the optional state attributes passing to the setState
function.
setState({
...state, ...{
name : "Geralt",
isMarried : "false"
} as unknown as IUser
});
Thus in the above example, the age
field is not set, and the default value is used, which is provided by the state
. The state override is done by the ...
or the spread operator.
Use Arrays in useState
Hook in TypeScript
Arrays can usually be used in useState
hooks while getting data from an API. The following code segment demonstrates this while fetching data and displaying it using useState
hooks.
interface IPost {
userId : number ;
id : number ;
title : string ;
body : string ;
}
export default App = () => {
const [ state, setState ] = React.useState<IPost[]>([]);
const getPosts = async () => {
const res : Response = await fetch("https://jsonplaceholder.typicode.com/posts");
const posts : IPost[] = await res.json();
setState(posts);
}
React.useEffect(() => {
getPosts();
}, []);
return (
<>
{
state.map( (post,index) => <div key={index}>
<h2>{post.title}</h2>
<div>{post.id}</div>
<p>{post.body}</p>
</div>
)
}
</>
)
}