javascript - React 使 useState 初始值有条件
问题描述
我正在尝试根据道具数据设置初始状态。
const Calculate({data}) => {
const [number, setNumber] = data === 'end' ? useState(5) : useState(0);
return (...)
}
这给了我一个错误:有条件地调用 React Hook "React.useState"。在每个组件渲染中,必须以完全相同的顺序调用 React Hooks。
所以我决定用 useEffect 更新我的代码:
const Calculate({data}) => {
const [number, setNumber] = useState(0);
useEffect(() => {
if (data === 'end') {
setNumber(5)
}
}, []);
}
但是,如果不需要,我宁愿不将状态最初设置为零。
或者我可以通过使初始值有条件来解决它吗?
const Calculate({data}) => {
const [number, setNumber] = useState(data === 'end' ? 5 : 0);
return (...)
}
这有什么副作用吗?为什么这行得通,而不是我最初的尝试?
解决方案
你可以在你的useState
钩子里使用一个三元组,它会工作得很好。但是,最好按以下方式将其包装在函数表达式中。
const [number, setNumber] = useState((data) => data === 'end' ? 5 : 0)
上面代码片段中的函数表达式在设置初始状态时只会被评估一次。将三元运算符包装在函数表达式中是有好处的。
假设data === 'end' ? 5 : 0
您不想使用昂贵计算的结果来设置初始状态,在这种情况下,您可以将其包装在一个函数表达式中,例如:
const [number, setNumber] = useState(() => expensiveFunction())
这更好,因为() => expensiveFunction()
将返回一个在初始渲染期间只评估一次的函数。然而,如果您不将expensiveFunction
函数表达式包装在内部,则每次您的组件呈现时都会对其进行评估并阻止代码的执行,直到expensiveFunction
返回一个值。
这种方法也称为Lazy initialization
.