我的意图是使用一个函数(由父组件接收,使用 useCallback
创建)作为 useEffect
中的依赖项,并且仅在函数更改时触发该效果。
考虑以下简单组件:
function MyComponent(props) {
const [myState, setMyState] = useState(0);
useEffect(() => {
setMyState(props.calculate(1));
}, [props.calculate])
return <h1>{myState}</h1>;
}
它在 props 中接收一个函数 calculate
并从中计算 myState
。但是我得到了 linting 错误:
React Hook useEffect has a missing dependency: 'props'. Either include it or remove the dependency array.
我不明白为什么 props.calculate
不足以作为依赖项而我们需要 props
。我不想使用 props
因为那样效果会在每次渲染时重新触发,即使 calculate
没有改变。 (假设 calculate
是在父级中使用 useCallback
创建的)。
以下版本不会出现任何 linting 错误:
function MyComponentVersion2(props) {
const { calculate } = props;
const [myState, setMyState] = useState(0);
useEffect(() => {
setMyState(calculate(1));
}, [calculate])
return <h1>{myState}</h1>;
}
我的问题是:
MyComponent
的 linter 不正常?MyComponent
与 MyComponentVersion2
相比是否存在语义差异?我在此codesandbox中做了一个最小的例子
谢谢!
答案 0 :(得分:2)
这是因为调用 props.calculate(1)
隐式地将 props
作为 this
值传递给 calculate
,因此从技术上讲,结果可能取决于整个 props
对象(见this React issue)。对于解构的 calculate
调用,this
将是未定义的或全局对象,因此不依赖于 props
。
您可以通过将 (x) => {return x + 1;}
的定义中的 function (x) {console.log(this); return x + 1;}
替换为 calculate
来查看两个组件之间的区别。