【问题标题】:too many re-renders. when trying to update an object in array state太多的重新渲染。尝试更新数组状态的对象时
【发布时间】:2022-01-01 21:35:15
【问题描述】:

我正在尝试编写待办事项列表。我有一个包含所有任务作为对象的数组。 每个任务都有一个名为“已检查”的属性,以指示我是否已检查此任务。 当一个任务被检查时,我有 onClicked 函数,它改变了数组中指定任务的“检查”属性,在这一点上我有一个“重新渲染太多”的错误。 希望得到你的帮助..

import { useEffect, useState } from "react";
import react from "react";
import "./styles.css";

export default function ToDoList() {
  const [allTasks, setAllTasks] = useState([]);
  const [newTask, setNewTask] = useState({ value: "" });
  const [currentIndex, setCurrentIndex] = useState(0);

  const handleChanged = ({ target }) => {
    setNewTask({
      value: target.value,
      id: currentIndex,
      checked: false
    });
  };

  function onClicked() {
    if (newTask.value === "") return;
    setAllTasks((prev) => {
      return [newTask, ...prev];
    });
    setNewTask({ value: "" });
    setCurrentIndex((prevCurrentIndex) => prevCurrentIndex + 1);
  }

  const handleKeyPress = (event) => {
    if (event.keyCode === 13) {
      onClicked();
    }
  };

  const onCheck = (i) => {
    const task = { ...allTasks[i] };
    task.checked = !task.checked;

    const taskState = [...allTasks];
    taskState[i] = task;

    setAllTasks(taskState);
  };

  return (
    <div>
      <h1>
        <u>
          <b>To Do List</b>
        </u>
      </h1>
      <input
        value={newTask.value}
        onChange={handleChanged}
        onKeyDown={handleKeyPress}
      />
      <button onClick={onClicked} />
      <h1>{newTask.value}</h1>
      <lo>
        {allTasks.map((item, i) => (
          <li>
            {item.checked ? (
              <input type="checkbox" checked={true} onClick={onCheck(i)} />
            ) : (
              <input type="checkbox" checked={false} onClick={onCheck(i)} />
            )}

            {item.value}
          </li>
        ))}
      </lo>
    </div>
  );
}

【问题讨论】:

    标签: reactjs checkbox setstate


    【解决方案1】:

    在渲染后立即调用onCheck 函数(使用函数的result,即undefined,作为实际的点击处理程序):

    onClick={onCheck(i)}
    

    哪个更新状态,哪个触发重新渲染,哪个调用函数,哪个更新状态等等等等。

    在渲染期间不要立即调用onCheck。当用户点击元素时调用它,方法是将其包装在一个函数中:

    onClick={() => onCheck(i)}
    

    这会将函数本身设置为点击处理程序,并且仅在发生这种情况时调用该函数。

    【讨论】:

    • 谢谢你。它的效果很好。但我不明白为什么。为什么如果我写 onClick={onCheck(i)} 它会自动调用该函数?不依赖点击?
    • @asafH:因为在 JavaScript 中,在函数引用后添加括号调用函数。所以onCheck 是函数引用,onCheck() 调用 函数。如果您不需要将特定值传递给函数,那么您可以直接使用引用:onClick={onCheck}。但是由于您确实需要传递一个特定的值,那么在这种情况下,您所做的就是从另一个函数中调用该函数,并将 that 函数引用传递给 onClick 属性。在这种情况下,一个单语句匿名箭头函数。
    • 谢谢你!很好的解释。
    猜你喜欢
    • 1970-01-01
    • 2020-11-01
    • 2023-02-09
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 2023-03-09
    • 2020-08-12
    • 2019-09-27
    相关资源
    最近更新 更多