Borislav Hadzhiev
Wed Apr 20 2022·2 min read
Photo by Soroush Karimi
To type the useState
hook as an array of strings in React, use the hook's
generic, e.g. const [names, setNames] = useState<string[]>([])
. The state
variable can be initialized to an empty array or an array of strings and will
only accept string values.
import {useState} from 'react'; const App = () => { // 👇️ const names: string[] const [names, setNames] = useState<string[]>([]); return ( <div> <button onClick={() => setNames(prevNames => [...prevNames, 'Bob'])}> Add name </button> {names.map((element, index) => { return ( <div key={index}> <h2>{element}</h2> </div> ); })} </div> ); }; export default App;
We used a generic to type the useState hook correctly while initializing the hook with an empty array.
Had we not used the generic, e.g. useState<string[]>([])
when typing the hook,
the type of the state variable would be never[]
, in other words, an array that
will never contain any elements.
If you pass even a single empty string to the array, TypeScript will be able to infer the type of the state variable.
import {useState} from 'react'; const App = () => { // 👇️ const names: string[] const [names, setNames] = useState(['']); return ( <div> <button onClick={() => setNames(prevNames => [...prevNames, 'Bob'])}> Add name </button> {names.map((element, index) => { return ( <div key={index}> <h2>{element}</h2> </div> ); })} </div> ); }; export default App;
Notice that we didn't even have to use a generic to type the state variable. TypeScript was able to infer the type based on the provided initial value.
useState
hook, especially when working with arrays and objects.If we try to add a value of a different type to the state array, we would get a type checking error.
import {useState} from 'react'; const App = () => { // 👇️ const names: string[] const [names, setNames] = useState<string[]>([]); // ⛔️ Argument of type '(prevNames: string[]) => (string | number)[]' is not // assignable to parameter of type 'SetStateAction<string[]>'. setNames(prevNames => [...prevNames, 1000]); return ( <div> <button onClick={() => setNames(prevNames => [...prevNames, 'Bob'])}> Add name </button> {names.map((element, index) => { return ( <div key={index}> <h2>{element.toUpperCase()}</h2> </div> ); })} </div> ); }; export default App;
The example shows how trying to add a number to a state array that is typed as
string[]
causes the type checker to error out.