use*_*977 5 javascript reactjs react-hooks
我正在尝试根据道具中的数据设置初始状态。
const Calculate({data}) => {
const [number, setNumber] = data === 'end' ? useState(5) : useState(0);
return (...)
}
Run Code Online (Sandbox Code Playgroud)
这给了我一个错误:React Hook“React.useState”被有条件地调用。React Hooks 必须在每个组件渲染中以完全相同的顺序调用。
所以我决定用 useEffect 更新我的代码:
const Calculate({data}) => {
const [number, setNumber] = useState(0);
useEffect(() => {
if (data === 'end') {
setNumber(5)
}
}, []);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果不需要,我宁愿不将状态最初设置为零。
或者我可以通过将初始值设为有条件来解决这个问题吗?
const Calculate({data}) => {
const [number, setNumber] = useState(data === 'end' ? 5 : 0);
return (...)
}
Run Code Online (Sandbox Code Playgroud)
这有什么副作用吗?为什么这个可行,而不是我最初的尝试?
Ris*_*abh 12
您可以在钩子中使用三元useState,它会正常工作。但是,最好按以下方式将其包装在函数表达式中。
const [number, setNumber] = useState((data) => data === 'end' ? 5 : 0)
Run Code Online (Sandbox Code Playgroud)
上面代码片段中的函数表达式在设置初始状态时只会被计算一次。将三元运算符包装在函数表达式内有一个好处。
假设data === 'end' ? 5 : 0您不想使用昂贵的计算结果来设置初始状态,在这种情况下您可以将其包装在函数表达式中,例如:
const [number, setNumber] = useState(() => expensiveFunction())
Run Code Online (Sandbox Code Playgroud)
这更好,因为() => expensiveFunction()将返回一个在初始渲染期间仅计算一次的函数。然而,如果您不将其包装expensiveFunction在函数表达式内,则每次组件渲染时都会对其进行求值,并阻止代码的执行,直到expensiveFunction返回一个值。
这种方法也称为Lazy initialization.
\n\n这有什么副作用吗?为什么这会起作用而不是我最初的尝试?
\n
不,没有副作用,这就是您的情况的方法。它在您的情况下不起作用,因为您违反了挂钩规则之一:
\n\n\n不要\xe2\x80\x99t 在循环、条件或嵌套函数内调用 Hooks。\n相反,请始终在 React 函数的顶层、\n在任何早期返回之前使用 Hooks。通过遵循此规则,您可以确保每次组件渲染时\n以相同的顺序调用 Hooks。\n这\n\xe2\x80\x99s 允许 React 在多个 useState 和 useEffect 调用之间\n正确保留 Hooks 的状态。(如果您\xe2\x80\x99很好奇,\n我们\xe2\x80\x99将在下面深入解释这一点。)
\n
最初,您的useState调用本身被包装在一个条件中,这是一个问题。您的新方法不再是这种情况。
| 归档时间: |
|
| 查看次数: |
15734 次 |
| 最近记录: |