推送到数组时反应状态无法正确更新

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了推送到数组时反应状态无法正确更新相关的知识,希望对你有一定的参考价值。

我已经在这个问题上摸爬了一段时间,我想知道为什么我的状态不会更新。我已经写了一个功能组件,我知道我缺少一些小东西,但是我不知道是什么。

目标是更新一个包含选中框名称的数组(从输入框更新)。这是我的代码

export default function Projects(props) 
  const [checkedBoxes, setCheckedBoxes] = useState([]);

  const onCheck = box => 
    let boxes = [...checkedBoxes];
    console.log(`Checking box $box`);
    if (document.getElementById(box).checked) 
      console.log(`Box checked`);
      //Add box
      boxes.push(box);
     else 
      console.log(`Removing box`)
      //Remove box
      let index = 0;
      for (let i = 0; i < boxes.length; i++) 
        if (boxes[i] === box)
          index = i;
      
      boxes.splice(index, 1)
    
    console.log(`Boxes is now $boxes`)
    setCheckedBoxes(boxes);
    console.log(`Checked boxes is now: $checkedBoxes`)
    console.log(`Boxes length: $boxes.length`)
    console.log(`Checked boxes length: $checkedBoxes.length`)

console.log输出如下:

Checking box box1
Box checked
Boxes is now box1
Checked boxes is now: 
Boxes length: 1
Checked boxes length: 0

任何人都可以提供关于发生这种情况的原因的任何见解(或就如何存储此信息给我一个更好的主意?)。目标是让用户复选框,然后根据选中的复选框过滤其他状态(项目列表)。

谢谢

答案

反应状态更新是异步的,因此尝试在设置后立即记录新状态将仅记录当前状态。您可以使用效果在状态更新后记录状态。请记住将checkedBoxes添加到依赖项数组中,以便仅在效果更新时才调用效果的回调。

export default function Projects(props) 
  const [checkedBoxes, setCheckedBoxes] = useState([]);

  useEffect(() => 
    console.log(`Checked boxes is now: $checkedBoxes`)
    console.log(`Checked boxes length: $checkedBoxes.length`)
  , [checkedBoxes]);

  const onCheck = box => 
    let boxes = [...checkedBoxes];
    console.log(`Checking box $box`);
    if (document.getElementById(box).checked) 
      console.log(`Box checked`);
      //Add box
      boxes.push(box);
     else 
      console.log(`Removing box`)
      //Remove box
      let index = 0;
      for (let i = 0; i < boxes.length; i++) 
        if (boxes[i] === box)
          index = i;
      
      boxes.splice(index, 1)
    
    console.log(`Boxes is now $boxes`)
    console.log(`Boxes length: $boxes.length`)
    setCheckedBoxes(boxes);
  

以上是关于推送到数组时反应状态无法正确更新的主要内容,如果未能解决你的问题,请参考以下文章

将复选框值推送到状态 onChange 的数组

如何正确更新反应钩子状态中的数组

React JS将项目推送到数组以获取列表

推送到数组不会触发 vue 的反应性

$emit 对象到父组件,并推送到数组。数组中的对象仍然是反应性的,为啥?

反应表单,提交对象,然后将其推送到数组