web-dev-qa-db-fra.com

Façon correcte de taper l'état nullable lors de l'utilisation du hook useState de React

J'ai du mal à trouver comment taper la fonction useState car elle retourne un tuple. En substance, je dois fournir null comme valeur initiale pour email c'est-à-dire que je ne peux pas utiliser de chaîne vide ici.

J'ai alors la fonction setEmail pour mettre à jour cette valeur d'état, qui prend l'email comme chaîne.

idéalement, je voudrais taper mon useState pour qu'il s'attende à ce que la messagerie soit soit une chaîne soit nulle si possible. Pour le moment, il n'en hérite que comme 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>
}

L'erreur suivante est renvoyée pour la fonction setEmail car string dans l'argument de la fonction n'est pas un type valide pour null spécifié dans 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;
}
12
Ilja

vous pouvez utiliser les types mappés TS pour améliorer la lisibilité et préférez les valeurs non définies aux valeurs nulles

const { useState } = React;

function Example() {
  const [state, setState] = useState<Partial<{email: string, password: string}>>();

  function setEmail(email: string) {
    setState(prevState => ({ ...prevState, email }))
  }

  return <p>{state.email | ""}</p>
}
0
Adrien Gardou