javascript eslint希望我向useEffect添加一个依赖项,但这样做会导致无限循环

bzzcjhmw  于 2023-03-21  发布在  Java
关注(0)|答案(1)|浏览(139)

我知道这是一个常见的问题,但我很难为我的特殊情况想出一个解决方案。我的代码按预期工作,但我得到了一个关于useEffect中缺少依赖项的eslint警告。缺少的依赖项是一个将状态发送给父对象的函数,但如果我将其添加为依赖项,则会导致无限循环。
下面是我的子组件CheckboxGroup.js
itemIdcheckedState从它的子节点(CheckboxItem.js)中被提升,selectedItemIds的状态被更新。然后我使用了useEffect,因为selectedItemIds需要立即被提升到它的父节点(App.js)。正如你所看到的,它的依赖列表中缺少onSelectHandler

const CheckboxGroup = (props) => {
  const categoryName = props.items[0].category;

  const [selectedItemIds, setSelectedItemIds] = useState([
    ...props.defaultCheckboxIds,
  ]);

  const clickHandler = (itemId, checkedState) => {
    checkedState
      ? setSelectedItemIds((prev) => [...prev, itemId])
      : setSelectedItemIds((prev) => prev.filter((c) => c !== itemId));
  };

  //destructure prop
  const onSelectHandler = props.onSelectHandler;

  useEffect(() => {
    onSelectHandler(categoryName, selectedItemIds)
  }, [categoryName, selectedItemIds]);

  return (
    <ul className="card__inner">
      {props.items.map((item) => {
        return (
          <CheckboxItem
            isChecked={selectedItemIds.includes(item.id)}
            id={item.id}
            name={item.name}
            price={item.price}
            category={item.category}
            key={item.id}
            onClick={clickHandler}
          />
        );
      })}
    </ul>
  );
};

下面是App.js中的函数,它接收数据,然后更新selections状态。

const [selections, setSelections] = useState({
    chairs: 2,
    tables: 8,
    "large tables": [10, 12]
  });

  const selectionHandler = (selectedCategoryName, selectedItemIds) => {
    setSelections((prev) => ({
      ...prev,
      [selectedCategoryName]: selectedItemIds,
    }));
  };

所以我想知道是否有一种方法可以在useEffect中包含依赖项而不会触发无限循环,或者有一种替代方法可以提升状态,也许没有useEffect
任何帮助都感激不尽,谢谢。

cedebl8k

cedebl8k1#

你可以使用React中的useCallback来记忆selectionHandler。这样你就可以安全地将它添加到依赖数组中:

import { useCallback } from "react";
const selectionHandler = useCallback((selectedCategoryName, selectedItemIds) => {
  setSelections((prev) => ({
    ...prev,
    [selectedCategoryName]: selectedItemIds,
  }));
}, []);

相关问题