使用变形状态来计算带有反应钩子的新状态是否安全?

时间:2019-06-04 20:36:58

标签: reactjs react-hooks

是否使用变形状态来计算新状态安全?

例如:

const [clickCount, setClickCount] = useState(0);
//then later
setClickCount(clickCount + 1)

我知道使用this.state + 1的类是不可能的,最好的办法是使用提供前一状态的setState的重载。假设文档使用的示例与我上面的示例相似,并且没有提及,我认为它是安全的。直到我发现setState操作签名为:

type SetStateAction<S> = S | ((prevState: S) => S);

如果安全的话,我现在很好奇为什么可以有选择地为函数提供以前的状态。否则,当您破坏了应该同步的当前状态时,什么时候需要使用它?

编辑:

这是文档使用this.state讲述setState的内容:

  

setState()不会立即使this.state突变,而是创建一个   等待状态转换。调用此后访问this.state   方法可能会返回现有值。

     

不能保证对setState的调用的同步操作   并且可以批量调用以提高性能。

1 个答案:

答案 0 :(得分:0)

类似于类组件中的setState API如何接受函数作为参数,钩子也接受相同的函数。

official docs中:如果您想使用以前的重载中的新鲜状态,则始终可以传递函数。

  

这是否也意味着像这样。状态不能保证使用钩子在变形状态下发生了突变?

即使在类和钩子中获得状态的方式不同,setState API本身在这两种方法中也具有相似的实现。它仍然是异步的。因此,无论您如何访问状态(类中的this.state或钩子中的state),都可能根据您的代码使用陈旧状态。 示例:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(count + 1)}>Reset</button>
      <button onClick={() => setCount(count + 2)}>+</button>
    </>
  );
}


class Counter extends React.Component {
  constructor() {
    super();
    this.state = initialCount;
  }

  render() {
    <>
      Count: {count}
      <button onClick={() => this.setState(count + 1)}>Reset</button>
      <button onClick={() => this.setState(count + 2)}>+</button>
    </>
  }
}

已经通过两种方式实现了相同的组件。但是它们都不保证在后续的setState语句中将使用先前的状态值。因此,在这种情况下,最好在钩子和类中同时传递一个函数。