Borislav Hadzhiev
Wed Apr 20 2022·2 min read
Photo by Soroush Karimi
To type the useState
hook with null initial value in React, use the hook's
generic, e.g. const [name, setName] = useState<string | null>(null)
. The state
variable can be initialized to null
and set to the specified type later on in
your code.
import {useState} from 'react'; const App = () => { // 👇️ with objects const [state, setState] = useState<{ first: string | null; last: string | null; }>({first: null, last: null}); // 👇️ with other types const [name, setName] = useState<string | null>(null); return ( <div> <h2>Name: {name}</h2> <button onClick={() => setName('James Doe')}>Set name</button> <h2>First: {state.first}</h2> <h2>Last: {state.last}</h2> <button onClick={() => setState({first: 'Bob', last: 'Ross'})}> Set state </button> </div> ); }; export default App;
We used a
generic
to type the useState
hook correctly while passing it null
as an initial value.
Had we not used the generic, e.g. useState<string | null>(null)
when typing
the hook, the type of the state variable would be null
and we wouldn't be able
to change its value without getting a type checking error.
// 👇️ const name: string const [name, setName] = useState('');
Then TypeScript would be able to infer the type of the state variable and we wouldn't even have to use a generic to type it.
One thing to keep in mind when using null
as an initial value is that the type
of the state variable is the specified type OR null
.
This means that you would have to check and make sure that the type of the state
variable is not null
before you access any built-in methods on it.
// 👇️ const name: string | null const [name, setName] = useState<string | null>(null); // 👉️ name is string or null here if (name != null) { // 👉️ TypeScript knows that name is string here console.log(name.toUpperCase()); } console.log(name?.toUpperCase());
The first example shows how to use an if
statement that serves as a type guard
to get around the possibly null
value before calling a built-in method.
if
block, TypeScript knows that the name
variable is guaranteed to be of type string
, so we are allowed to call its toUpperCase()
method.The second example uses the
optional chaining (?.)
operator to short-circuit if the reference is nullish (null
or undefined
).
In other words, if the name
variable stores a null
value, the optional
chaining (?.) operator would short-circuit returning undefined
, instead of try
to access the toUpperCase()
method on a null
value and cause a runtime
error.