使用 React 的 useState 钩子时输入可空状态的正确方法
Posted
技术标签:
【中文标题】使用 React 的 useState 钩子时输入可空状态的正确方法【英文标题】:Correct way to type nullable state when using React's useState hook 【发布时间】:2019-04-19 16:55:10 【问题描述】:我无法弄清楚如何键入 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
方法的方法,即如果我将来使用自定义接口但想要初始值为空或未定义
【参考方案1】:
目前,TypeScript 编译器认为email
和password
的类型是null
(没有其他值)。您可以通过向 useState
调用提供显式类型参数来解决此问题,以便已知 email
和 password
的类型为 string
或 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>
【讨论】:
【参考方案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<UserType>();
,而这不起作用const [user, setUser] = useState<UserType>(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 实际上是个好主意,对我有帮助:)以上是关于使用 React 的 useState 钩子时输入可空状态的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
React 钩子表单不适用于来自 reactstrap 的输入