如何为 React 钩子(useState 等)做流类型注释?
Posted
技术标签:
【中文标题】如何为 React 钩子(useState 等)做流类型注释?【英文标题】:How to do flow type annotations for React hooks (useState, etc.)? 【发布时间】:2019-09-22 11:36:02 【问题描述】:我们应该如何使用带有反应钩子的流类型注释,例如useState
?我已经尝试搜索应该如何实现它们的一些示例,但找不到任何东西。
我试过了:
const [allResultsVisible, setAllResultsVisible]: [ boolean, (boolean) => void, ] = useState(false);
这不会引发任何与流程相关的错误,但我不确定这是否正确或注释钩子的最佳方式。如果我的尝试不正确或不正确,我应该怎么做?
【问题讨论】:
理想情况下,Flow 应该从useState(false)
推断类型(就像 TypeScript 一样),并且根本不需要注释。
使用类型参数const [loading, setLoading] = useState<boolean>(true);
【参考方案1】:
Flow 将类型推断为 shown in the PR,它为 Flow 库添加了对钩子的支持。
更新
正如我在另一个答案的 cmets 中所讨论的,生成的变量必须在上下文中使用才能使类型检查按预期工作。
const [loading, setLoading] = React.useState(true);
(loading: boolean);
setLoading('foo') // Flow error
对比
const [loading, setLoading] = React.useState(true);
setLoading('foo') // no Flow error
【讨论】:
你也可以使用类型参数const [loading, setLoading] = useState<boolean>(true);
【参考方案2】:
类型推断对我不起作用:
const [loading, setLoading] = React.useState(true) // boolean
setLoading('foo') // no Flow error
setLoading(1) // no Flow error
必须手动添加类型:
const [loading, setLoading]: [boolean, ((boolean => boolean) | boolean) => void] = React.useState(false)
setLoading('foo') // Flow error
setLoading(1) // Flow error
我有:
"react": "16.8.6",
"flow-bin": "0.100.0",
更新
正如@AndrewSouthpaw 指出的那样,loading
必须在某些情况下使用,否则setLoading
将无法正常工作。
这行得通:
const [loading, setLoading] = React.useState(true);
(loading: boolean);
setLoading('foo'); // Flow error
不用分号也一样:
const [loading, setLoading] = React.useState(true)
;(loading: boolean)
setLoading('foo') // Flow error
ESLint
ESLint no-unused-expressions 会因此报错。 eslint-plugin-flowtype 有固定版本flowtype/no-unused-expressions.
【讨论】:
看来您需要在某些情况下使用loading
,否则setLoading
将无法正常工作。 flow.org/try/…
如何通过“Try Flow”分享 Flow 示例:flow.org/try?未从该网站找到任何共享功能。
您可以通过复制浏览器中生成的 URL 来通过 Try Flow 进行分享。【参考方案3】:
如果可以从初始值推断出类型,则不需要为Flow添加类型信息,例如:
const [open, setOpen] = React.useState(false);
如果因为初始值是复杂对象而无法推断,则使用泛型分配类型,例如:
type Merchandize = |
name: string,
value: number,
|;
const [shoppingCare, setShoppingCart] = React.useState<Array<Merchandize>>([]);
【讨论】:
天哪,我正在找这个,谢谢你的回答。这解决了我的 Flow useState 类型问题!【参考方案4】:除了以上答案,
确保将// @flow
放在文件的最顶部,以使所有流功能正常工作。
没有将// @flow
放在顶部对我有用的唯一一种解决方案是:
const [allResultsVisible, setAllResultsVisible]: [ boolean, Function ] = useState(false);
【讨论】:
以上是关于如何为 React 钩子(useState 等)做流类型注释?的主要内容,如果未能解决你的问题,请参考以下文章
React:useState 钩子中的 setState 在啥情况下会导致重新渲染?
在对数组进行排序并传递它之后,React 钩子 useState/setState 不起作用
React - useState 钩子第一次和后续设置状态时的奇怪行为
是否可以使用 React 中的 useState() 钩子在组件之间共享状态?