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

时间:2019-06-03 10:28:40

标签: reactjs react-hooks use-effect

我具有以下功能:

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 Hook useEffect缺少依赖项'handleEnterPress'。

在第二个参数数组中添加handleEnterPress会有什么区别?

2 个答案:

答案 0 :(得分:0)

  

当我们在第二个参数数组中添加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的值(很多情况不是您的情况,但这是useEffect所期望的)
    而且您在handleEnterPress的依存关系中没有useEffect,因此不会产生影响。

  2. 然后value发生更改,效果就会发生清除

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

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

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

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

编辑:

chips发生变化时,handleEnterPress也发生变化,并且由于您没有将handleEnterPress添加到依赖数组中,因此,您将始终具有旧值handleEnterPress和也是chips的旧值。

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

答案 1 :(得分:0)

经过一番谷歌搜索后,我发现了一种更好的方法 我们可以将函数'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]);