如何为 React 钩子(useState 等)做流类型注释?

IT技术 reactjs flowtype
2021-05-04 13:47:55

我们应该如何使用带有 React 钩子的 Flow 类型注释,例如useState我试过寻找一些应该如何实施它们的例子,但找不到任何东西。

我试过这个:

const [allResultsVisible, setAllResultsVisible]: [ boolean, (boolean) => void, ] = useState(false);

这不会引发任何与流程相关的错误,但我不确定这是否正确或注释钩子的最佳方式。如果我的尝试不正确或不是最好的方法,我应该怎么做?

4个回答

Flow 推断类型,如PR所示,它为 Flow 库添加了对钩子的支持。

更新

正如我在另一个答案的评论中所讨论的那样,必须在上下文中使用结果变量才能使类型检查按预期工作。

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] = 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

如果可以从初始值推断出类型,则无需为Flow添加类型信息,例如:

const [open, setOpen] = React.useState(false);

如果因为初始值是复杂对象而无法推断,则使用泛型来分配类型,例如:

type Merchandize = {|
  name: string,
  value: number,
|};

const [shoppingCare, setShoppingCart] = React.useState<Array<Merchandize>>([]);

除了上面的回答,

确保放在// @flow文件的最顶部,以使所有流程功能正常工作。

唯一对我有用而不放在// @flow顶部的解决方案是:

const [allResultsVisible, setAllResultsVisible]: [ boolean, Function ] = useState(false);