React如何实现useState初始值条件设置 避免Hook条件调用报错
1. 你最后采用的写法不存在副作用,是合法的可用写法
const Calculate({data}) => { const [number, setNumber] = useState(data === 'end' ? 5 : 0); return (...) }
这种写法的本质是条件判断仅用来计算useState的入参,不会影响useState本身的调用逻辑,完全符合React Hook的使用规则。
需要额外注意的是:useState的初始值仅在组件第一次挂载时生效,后续如果props传入的data发生变化,number状态不会自动同步更新。如果你的业务逻辑需要响应data的变更更新状态,可以额外增加依赖为data的useEffect处理同步逻辑;如果number不需要在组件内部自主更新,也可以直接去掉state,在渲染时直接根据data计算值即可。
另外你之前使用useEffect的写法实际存在性能损耗:空依赖的useEffect仅在组件挂载后执行,会导致组件额外多渲染一次,且如果挂载后data才更新为end也不会触发状态同步,实用性远低于直接在useState初始值中判断的写法。
2. 两种写法的合法性差异原因
React Hook有核心使用规则:所有Hook必须在组件渲染的最顶层调用,不能包裹在条件判断、循环、嵌套函数中。
React底层是按Hook的调用顺序来存储和对应每个Hook的状态的,如果每次渲染时Hook的调用次数、调用顺序不一致,React就无法正确匹配到每个Hook对应的状态值,因此会直接抛出规则校验错误。
最初的条件调用useState写法不合法的原因
// 错误写法 const Calculate({data}) => { const [number, setNumber] = data === 'end' ? useState(5) : useState(0); return (...) }
这段代码中useState的调用是被条件控制的:如果data === 'end'就调用第一个useState,否则调用第二个useState。如果两次渲染时data的值发生变化,就会导致两次渲染时useState的调用顺序/次数不一致,直接违反了Hook的调用规则,因此运行会报错。
把判断写在useState参数中的写法合法的原因
这种写法下,不管data的值是什么,useState都会被调用且仅被调用一次,调用顺序永远固定,完全符合Hook的调用规则。三目运算只是在计算传给useState的初始值参数,不会对Hook的调用逻辑产生任何影响,因此可以正常运行。
内容的提问来源于stack exchange,提问作者user2456977

