为什么 useState 钩子会这样?

时间:2020-12-23 21:12:03

标签: reactjs react-hooks

我正在构建一个组件,它为用户提供多个计数器,他们可以使用 useState 钩子递增或递减。

 const [counters,setCounters] = useState([0,0,0,0]);
  return (
    counters.map((ele,i) => {
      return (
          <div key={i}>
            <p key='0'>{ele}</p>

            <button key='1' onClick={() => {
            counters[i]++; setCounters(counters);
            }}>+</button>

            <button key='2' onClick={() => {
            var t = [...counters]; t[i]--;
            setCounters(t);
            }}>-</button>

          </div>
      );
    })
  );

当我按下“+”按钮并增加 counters 变量的值,然后将其传递给 setCounters 时,没有可见的变化(

标签内的值没有变化)。但是,当我对计数器数组的副本执行相同操作时,不仅操作有效,而且结果还反映了我按下“+”按钮的次数,即按下增量按钮时未反映的更改是现在也是结果的一部分。

此外,如果我在增加 counters 变量后将其值记录到控制台(counters[i]++),那么我可以看到该值已更改,但是 p 标记中的值是相同的。这让我相信由于某种原因这个组件没有被渲染。为什么改变状态变量本身会导致这种情况发生?

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

在这一行中,您正在尝试变异 state,但您不应该这样做。

counters[i]++;

相反,创建一个新数组并将其传递给 setCounter 方法。 或者,更好的是,将函数传递给 setCounter 方法,遍历数组并仅更改您需要的元素。

const [counters,setCounters] = useState([0,0,0,0]);
return (
  counters.map((ele,i) => {
    return (
      <div key={i}>
        <p key='0'>{ele}</p>

        <button key='1' onClick={() => {
          setCounters((prev) => prev
            .map((counter, index) => index === i ? ++counter: counter));
        }}>+</button>

        <button key='2' onClick={() => {
          var t = [...counters]; t[i]--;
          setCounters(t);
        }}>-</button>

      </div>
    );
  })
);