我们可以在 useEffect 中使用函数作为第二个参数吗

IT技术 reactjs react-hooks use-effect
2021-05-06 01:22:50

我有以下功能:

function handleEnterPress(e) {
    if (e.keyCode === 13) {
      if (value !== "") {
        let toAdd = true;
        chips.forEach(chip => {
          if (chip.value === value) {
            toAdd = false;
          }
        });
        if (toAdd) {
          let chipsCopy = [...chips, { value, isDisabled: false }];
          setChips(chipsCopy);
        }
      }
      setValue("");
    }
  }

我有以下内容useEffect

useEffect(() => {
    inputRef.current.addEventListener("keyup", handleEnterPress);
    return () =>
      inputRef.current.removeEventListener("keyup", handleEnterPress);
  }, [value]);

现在react给了我一个警告:

React Hook useEffect 缺少依赖项“handleEnterPress”。

当我们添加handleEnterPress第二个参数数组时有什么区别

2个回答

当我们在第二个参数数组中添加 handleEnterPress 有什么区别。

为你?更干净的代码,没有警告。
为了react?就是它与useEffect.

要删除此警告,您需要添加handleEnterPress到依赖项数组useEEfect

useEffect(() => {
    inputRef.current.addEventListener("keyup", handleEnterPress);
    return () =>
      inputRef.current.removeEventListener("keyup", handleEnterPress);
  }, [value, handleEnterPress]);

你需要这个的原因是因为 react 不知道做handleEnterPress什么,或者是什么。如果handleEnterPress是一个变量并且它的值发生了变化怎么办?如果您更改,handleEnterPress您将需要再次“运行”效果,但如果您只使用[value],则handleEnterPress更改时它不会“运行” 在你的情况下,也许它永远不会改变,但react不能知道,所以......它告诉你添加为依赖项。

例如

1 . 在 中useEffect,您添加了一个事件侦听器。

inputRef.current.addEventListener("keyup", handleEnterPress);
  1. 但是然后你改变了handleEnterPress一些 how的值(很多这不是你的情况,但它是预期的useEffect
    并且你没有handleEnterPress依赖于useEffect,所以它不会运行效果。

  2. 然后value改变和效果的清理发生

    () => inputRef.current.removeEventListener("keyup", handleEnterPress);
    

在这部分中,您将尝试handleEnterPress使用 的新值删除handleEnterPress,而不是第一步中的值,因此您将尝试删除不存在的事件侦听器。

handleEnterPress永远不会删除包含旧值的第一个

这很糟糕,这就是您需要添加handleEnterPress为依赖项的原因

编辑:

chips更改时,handleEnterPress也会更改,并且因为您没有添加handleEnterPress到依赖数组,您将始终拥有 的旧值handleEnterPress和 的旧值chips

我的回答中解释了您的情况,是情况发生handleEnterPress变化,但事件侦听器仍然具有旧值handleEnterPress

经过一番谷歌搜索后,我找到了一个更好的方法来做到这一点我们可以将函数“handleEnterPress”放在 useEffect 本身中:

useEffect(() => {
    function handleEnterPress(e) {
      if (e.keyCode === 13) {
        if (value !== "") {
          let toAdd = true;
          chips.forEach(chip => {
            if (chip.value.toUpperCase() === value.toUpperCase()) {
              toAdd = false;
            }
          });
          if (toAdd) {
            let chipsCopy = [...chips, { value, isDisabled: false }];
            setChips(chipsCopy);
          }
        }
        setValue("");
      }
    }
    inputRef.current.addEventListener("keyup", handleEnterPress);
    return () =>
      inputRef.current.removeEventListener("keyup", handleEnterPress);
  }, [value, chips]);