首页 > 解决方案 > 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 (...)
}

这有什么副作用吗?为什么这行得通,而不是我最初的尝试?

标签: javascriptreactjsreact-hooks

解决方案


你可以在你的useState钩子里使用一个三元组,它会工作得很好。但是,最好按以下方式将其包装在函数表达式中。

const [number, setNumber] = useState((data) => data === 'end' ? 5 : 0)

上面代码片段中的函数表达式在设置初始状态时只会被评估一次。将三元运算符包装在函数表达式中是有好处的。

假设data === 'end' ? 5 : 0您不想使用昂贵计算的结果来设置初始状态,在这种情况下,您可以将其包装在一个函数表达式中,例如:

const [number, setNumber] = useState(() => expensiveFunction())

这更好,因为() => expensiveFunction()将返回一个在初始渲染期间只评估一次的函数。然而,如果您不将expensiveFunction函数表达式包装在内部,则每次您的组件呈现时都会对其进行评估并阻止代码的执行,直到expensiveFunction返回一个值。

这种方法也称为Lazy initialization.


推荐阅读