我们可以在 useEffect 中使用函数作为第二个参数吗 [英] Can we use a function as second arguments in useEffect

查看:219
本文介绍了我们可以在 useEffect 中使用函数作为第二个参数吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下功能:

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]);

现在反应给我一个警告:

Now react gives me a warning:

React Hook useEffect 缺少依赖项handleEnterPress".

React Hook useEffect has a missing dependency 'handleEnterPress'.

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

What difference does it make when we add handleEnterPress in second argument array?

推荐答案

在第二个参数数组中添加 handleEnterPress 有什么不同.

What difference does it make when we add handleEnterPress in second argument array.

为了你?没有警告的更干净的代码.
为了反应?就是它与 useEffect 一起工作的方式.

For you? Cleaner code without warnings.
For React? Is just the way it works with useEffect.

要消除这个警告,需要在useEEfect

To remove this warning, you need to add handleEnterPress to the dependency array of the useEEfect

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

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

The reason why you need this, is because react can't know what handleEnterPress do, or what is. What if handleEnterPress is a variable and it's value have changed? If you change handleEnterPress you will need to 'run' the effect again, but if you only use [value], it won't 'run' when handleEnterPress changes. In your case, maybe it will never change, but react can't know that, so... it tells you to add as a dependency.

例如

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

1 . In useEffect, you add an event listener.

inputRef.current.addEventListener("keyup", handleEnterPress);

  1. 然后你改变了 handleEnterPress 的值(很多这不是你的情况,但它是 useEffect 所期望的)
    并且您在 useEffect 的依赖项中没有 handleEnterPress,因此它不会运行效果.

  1. But then you change the value of handleEnterPress some how (many this is not your case but it's something expected from useEffect)
    And you don't have handleEnterPress in the dependency of useEffect, so it don't run the effect.

然后value改变,效果的清理发生

Then value changes and the cleanup of the effect happens

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

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

In this part you will try to remove handleEnterPress with the new value of the handleEnterPress, but not the one in the first step, so you are trying to remove an event listener that don't exists.

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

The first handleEnterPress containing the old values will never be removed.

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

This is bad and it's the reason why you need to add handleEnterPress as a dependency

chips 改变时,handleEnterPress 也会改变,并且因为你没有将 handleEnterPress 添加到依赖数组,你将始终拥有handleEnterPress 的旧值以及 chips 的旧值.

When chips change, handleEnterPress changes too, and because you don't add handleEnterPress to the depéndency array, you will always have the old value of handleEnterPress and also the old value of chips.

你的情况在我的回答中有解释,就是 handleEnterPress 改变的情况,但事件监听器仍然具有 handleEnterPress

Your case is explained in my answer, is the case where handleEnterPress changes, but the event listener still have the old value of handleEnterPress

这篇关于我们可以在 useEffect 中使用函数作为第二个参数吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆