【问题标题】:Array not updating on first click第一次单击时数组未更新
【发布时间】:2021-05-16 19:09:24
【问题描述】:

制作一个小型待办事项应用程序,我想添加在检查任务时将检查的任务放入数组的功能。第一次单击任务控制台时会显示一个空数组,然后在取消选中并再次选中时,我的数组会更新。为什么需要两次单击才能更新数组?

function SelectTodo({ todo }) {
  const [checkboxChecked, setCheckboxChecked] = React.useState([]);

  const handleInputChange = (e) => {
    const checked = e.target.checked;
    let value = e.target.value;

    if (checked) {
      setCheckboxChecked((prevChecked) => [...prevChecked, value]);
      console.log("checkBoxArrray:" + checkboxChecked);
    } else {
      console.log("unchecked");
    }
  };

  return (
    <label className="todo-list__label">
      <div className="form-check form-check-inline">
        <input
          className="form-check-input"
          type="checkbox"
          name="task"
          id="inlineCheckboxh1"
          value={todo}
          onChange={handleInputChange}
        />
        <label className="form-check-label" htmlFor="inlineCheckboxh1">
          {todo}
        </label>
      </div>
    </label>
  );
}

ReactDOM.render(<SelectTodo todo={5} />, document.getElementById("root"));
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

【问题讨论】:

  • 能否提供codesandbox 或类似的代码链接?

标签: arrays reactjs


【解决方案1】:

在 React 中设置状态为 async 进程。

这意味着,调用setCheckboxChecked 并立即尝试读取checkboxChecked 的值会得到当前值而不是更新值。

这意味着数组实际上正在更新,但您只记录旧值,因此看起来需要单击两次。

如果您想检查更新后的值,请执行此操作。

setCheckboxChecked((prevChecked) => {
    const updated = [...prevChecked, value];
    console.log(updated);
    return updated;
});

【讨论】:

  • Nisanth Reddy,感谢您的反馈!记下了。
【解决方案2】:

您无法从当前状态访问更新后的状态。请参阅useState set method not reflecting change immediately 了解更多信息。

您可以做的是在状态变量更新时触发效果并在此处打印更新后的数组:

React.useEffect(() => {
  console.log("checkBoxArrray:" + checkboxChecked);
}, [checkboxChecked]);

Nisanth Reddy 提出的解决方案也有效。


完整的工作示例:

function SelectTodo({ todo }) {
  const [checkboxChecked, setCheckboxChecked] = React.useState([]);

  const handleInputChange = (e) => {
    const checked = e.target.checked;
    let value = e.target.value;

    if (checked) {
      setCheckboxChecked((prevChecked) => [...prevChecked, value]);
    } else {
      console.log("unchecked");
    }
  };
  
  React.useEffect(() => {
    console.log("checkBoxArrray:" + checkboxChecked);
  }, [checkboxChecked]);

  return (
    <label className="todo-list__label">
      <div className="form-check form-check-inline">
        <input
          className="form-check-input"
          type="checkbox"
          name="task"
          id="inlineCheckboxh1"
          value={todo}
          onChange={handleInputChange}
        />
        <label className="form-check-label" htmlFor="inlineCheckboxh1">
          {todo}
        </label>
      </div>
    </label>
  );
}

ReactDOM.render(<SelectTodo todo={5} />, document.getElementById("root"));
<div id="root" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

【讨论】:

    【解决方案3】:

    检查以下解决方案,添加数据有一些条件可以跳过,从中可以获得即时更新的数组

      const [updated_chat, setUpdatedChat] = useState([]);
      const [messages_array, setMessagesArray] = useState([]);
    
    
      if (onMessage && userData?.user != text["userId"]) {
        if (updated_chat) {
          updated_chat.push(text);
          setMessagesArray(prevChecked => [...prevChecked, text]);
        }
      }
    
    console.log(messages_array);
    

    【讨论】:

      猜你喜欢
      • 2018-11-14
      • 2020-10-18
      • 2013-03-05
      • 1970-01-01
      • 2013-01-06
      • 2019-11-05
      • 2020-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多