【问题标题】:useEffect throw warning for dependecyuseEffect 对依赖项抛出警告
【发布时间】:2019-12-14 15:06:36
【问题描述】:

我有一个具有受控状态的下拉菜单。如果用户更改了下拉值并且输入不为空,则触发从其他组件传递的函数。

export default ({ triggerChange, inputVal }) => {
  const [dropdown, setDropdown] = useState(1);

  useEffect(() => {
    if (inputVal) {
      triggerChange(dropdown);
    }
  }, [dropdown]); // this line throw a warning

  const handleChange = e => {
    setDropdown(e.target.value);
  };

  return (
    <div>
      <select onChange={handleChange}>
        <option value="1">1</option>
        <option value="2">2</option>
      </select>
    </div>
  );
};

codesandbox

错误

React Hook useEffect 缺少依赖项:'inputVal' 和 '触发改变'。要么包含它们,要么删除依赖数组。 如果 'triggerChange' 变化太频繁,请找到 定义它并将该定义包装在 useCallback 中。 (react-hooks/exhaustive-deps)

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    将这些添加到依赖项中:

    useEffect(() => {
      if (inputVal) {
        triggerChange(dropdown);
      }
    }, [dropdown, inputVal]);
    

    这只会在 dropdowninputVal 值发生变化时重新运行效果。

    对于triggerChange

    如果dropdown频繁变化,使用useCallback钩子。

    // Parent.js
    const memoizedTriggerChange = useCallback(
      () => {
        triggerChange(dropdown);
      },
      [dropdown],
    );
    
    useEffect(() => {
      if (inputVal) {
        memoizedTriggerChange();
      }
    }, [inputVal]);
    

    编辑

    基于 OPs 代码框

    // index.js
    const triggerChange = useCallback(() => {
      console.log("call api");
    }, []); // not depending on inputVal to prevent firing if inputVal changes
    
    // AnotherComp.js
    useEffect(() => {
      triggerChange(dropdown);
    }, [dropdown, triggerChange]);
    

    【讨论】:

    • 将 inputVal 添加为依赖项不会丢弃警告 codesandbox.io/s/busy-browser-cusyb
    • 如果我将 inputVal 添加为 dep,非常中风会触发我不想要的 triggerChange。
    • useCallback 有什么用?您的代码会在应用首次加载时触发 triggerChange。
    • @Hanz 当您将函数作为道具传递时,您需要记住它(即确保该函数不是“新”,这会导致重新渲染)
    • @Hanz useEffect 就像 componentDidMount。所以如果你想在第一次加载时阻止triggerChange,添加一个条件来阻止它。
    【解决方案2】:
    useEffect(() => {
        if (inputVal) {
          triggerChange(dropdown);
        }
      }, [dropdown]); // this line throw a warning
    

    如果您注意到,在这段代码中,inputValtriggerChangedropdown 是变量,它们是 useEffect 挂钩的依赖项,因为只要对上述任何依赖项进行任何更改,都会触发 useEffect。

    为了满足 useEffect hook 的基本工作原理,我们应该在 useEffect 的数组参数中传递这些依赖关系。

      useEffect(() => {
        if (inputVal) {
          triggerChange(dropdown);
        }
      }, [dropdown, triggerChange, inputVal]);
    

    【讨论】:

    猜你喜欢
    • 2021-07-12
    • 2021-08-13
    • 2022-01-02
    • 2020-11-21
    • 2020-05-06
    • 1970-01-01
    • 1970-01-01
    • 2022-04-04
    • 1970-01-01
    相关资源
    最近更新 更多