Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct way to type nullable state when using React's useState hook

I am having trouble figuring out how to type useState function since it returns a tuple. In essence, I have to provide null as initial value for email i.e. lets assume I can't use empty string here.

I then have setEmail function to update this state value, which takes in email as string.

ideally I would like to type my useState so it expects email to be either string or null if possible. At the moment it inherits it as only null

import * as React from "react";  const { useState } = React;  function Example() {   const [state, setState] = useState({ email: null, password: null });    function setEmail(email: string) {     setState(prevState => ({ ...prevState, email }))   }    return <p>{state.email}</p> } 

Following error is returned for setEmail function since string in function argument is not valid type for null specified in useState()

[ts] Argument of type '(prevState: { email: null; password: null; }) => { email: string; password: null; }' is not assignable to parameter of type 'SetStateAction<{ email: null; password: null; }>'.   Type '(prevState: { email: null; password: null; }) => { email: string; password: null; }' is not assignable to type '(prevState: { email: null; password: null; }) => { email: null; password: null; }'.     Type '{ email: string; password: null; }' is not assignable to type '{ email: null; password: null; }'.       Types of property 'email' are incompatible.         Type 'string' is not assignable to type 'null'. [2345] (parameter) prevState: {     email: null;     password: null; } 
like image 596
Ilja Avatar asked Nov 16 '18 13:11

Ilja


People also ask

How do I change state with useState Hook?

To update the state, call the state updater function with the new state setState(newState) . Alternatively, if you need to update the state based on the previous state, supply a callback function setState(prevState => newState) .

How do you give a type on useState?

To type the useState hook as an object in React, use the hook's generic, e.g. const [employee, setEmployee] = useState<{name: string; salary: number}>({name: '',salary: 0}) . The state variable will only accept key-value pairs of the specified type. Copied!

What does useState null mean?

The useState hook returns an array where the first position (index 0) is the state and the second position (index 1) is the setter for that state. So when using useState(null)[1] you are only getting the setter for that state.

What is the type of useState Hook?

Initialize useState useState accepts an initial state and returns two values: The current state. A function that updates the state.


Video Answer


1 Answers

Currently, the TypeScript compiler thinks the type of email and password are null (and no other value). You can resolve this by providing an explicit type parameter to the useState call so that the types of email and password are known to be string or null.

const { useState } = React;  function Example() {   const [state, setState] = useState<{email: null | string, password: null | string}>({ email: null, password: null });    function setEmail(email: string) {     setState(prevState => ({ ...prevState, email }))   }    return <p>{state.email}</p> } 
like image 129
Nurbol Alpysbayev Avatar answered Sep 27 '22 02:09

Nurbol Alpysbayev