【问题标题】:Correct way to type nullable state when using React's useState hook使用 React 的 useState 钩子时输入可空状态的正确方法
【发布时间】:2023-03-07 14:29:01
【问题描述】:

我无法弄清楚如何键入 useState 函数,因为它返回一个元组。本质上,我必须提供null 作为email 的初始值,即假设我不能在这里使用空字符串。

然后我有setEmail 函数来更新这个状态值,它将电子邮件作为字符串接收。

理想情况下,我想输入我的useState,因此如果可能,它希望电子邮件为字符串或空值。目前它只继承它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>
}

setEmail 函数返回以下错误,因为函数参数中的 string 不是 useState() 中指定的 null 的有效类型

[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;
}

【问题讨论】:

  • 当你用空字符串改变null时会发生什么?我的意思是如果你使用useState({email: "", password: ""})?
  • @lomse 可以解决这个问题,但正如我在问题中提到的那样,我想找出一种使用 someType | null 方法的方法,即如果我将来使用自定义接口但想要初始值为空或未定义

标签: reactjs typescript react-hooks


【解决方案1】:

目前,TypeScript 编译器认为emailpassword 的类型是null(没有其他值)。您可以通过向 useState 调用提供显式类型参数来解决此问题,以便已知 emailpassword 的类型为 stringnull

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>
}

【讨论】:

    【解决方案2】:

    这已经在几个地方得到解决:

    https://dev.to/busypeoples/notes-on-typescript-react-hooks-28j2

    https://codewithstyle.info/Using-React-useState-hook-with-TypeScript/

    TLDR:当初始状态为空时,将类型参数传递给 setState

    例如:

    const [email, setEmail] = useState<string>();
    

    【讨论】:

    • 对象呢?
    • @refaelio 即使对于对象,如果您将括号保持为空,如果您定义了接口或类型,也不会导致问题。例如,这适用于const [user, setUser] = useState&lt;UserType&gt;();,而这不起作用const [user, setUser] = useState&lt;UserType&gt;(null);
    【解决方案3】:

    您可以使用 TS 映射类型来提高可读性,并且更喜欢 undefined 而不是 null 值

    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>
    }
    

    【讨论】:

    • 我认为您应该评论/编辑接受的答案,因为您的答案不那么易读,并且对现有答案没有额外的好处。
    • 我认为这个解决方案更好,因为它使用更少的字符:重复 null | xxx 四次不会提高可读性?
    • 拥有null 属性和完全没有它们是不一样的。
    • 使用 Partial 实际上是个好主意,对我有帮助:)
    猜你喜欢
    • 2020-06-24
    • 2020-04-29
    • 2020-07-31
    • 2019-08-06
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多