如何在反应中处理自定义挂钩的依赖项数组
How to handle dependencies array for custom hooks in react
我正在创建一个自定义挂钩并想定义一个可选参数,以便我可以在需要时传入额外的依赖项。我的代码类似于以下代码段:
import { useEffect } from 'react';
function useCustomHook(param1, extraDeps) {
useEffect(() => {
// do something with param1 here
}, [param1, ...extraDeps])
}
react-hooks/exhaustive-deps 发出警告
React Hook useEffect has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies
有人知道如何解决该警告吗?或者将 deps 数组传递给自定义挂钩不是一个好习惯?
对于那些对为什么需要 extraDeps 感兴趣的人。这是一个例子:
const NewComponent = (props) => {
[field1, setField1] = useState()
[field2, setField2] = useState()
// I only want this to be called when field1 change
useCustomHook('.css-selector', [field1]);
return <div>{field1}{field2}</div>;
}
您可以这样做:
将状态移动到您的自定义挂钩,运行 对其产生影响并 return 它。
类似于:
Component.js
function Component() {
const [field,setField] = useCustomHook(someProps);
}
useCustomHook.js
import {useState, useEffect} from 'react';
function useCustomHook(props) {
const [field,setField] = useState('');
useEffect(()=>{
// Use props received and perform effect after changes in field 1
},[field1]);
return([
field,
setField
]);
}
我认为问题在于您如何在自定义挂钩上创建依赖项数组。每次你这样做 [param1, ... extraDeps]
你都在创建一个新数组,所以 React 总是将它们视为不同的。
尝试将自定义挂钩更改为:
function useCustomHook(deps) {
useEffect(() => {
// do something with param1 here
}, deps)
}
然后像
一样使用它
const NewComponent = (props) => {
[field1, setField1] = useState()
[field2, setField2] = useState()
// I only want this to be called when field1 change
useCustomHook(['.css-selector', field1]);
return <div>{field1}{field2}</div>;
}
希望对您有所帮助!
我遇到了类似的问题,我希望在某些额外的依赖项发生更改时执行效果。
我没有设法提供这些额外的依赖关系,而是通过向调用者提供我希望执行的回调 并让他在需要时使用它来绕过 。
示例:
// This hook uses extraDeps unknown by EsLint which causes a warning
const useCustomEffect = (knowDep, extraDeps) => {
const doSomething = useCallback((knownDep) => {/**/}, [])
useEffect(() => {
doSomething(knownDep)
}, [doSomething, knownDep, ...extraDeps]) // Here there is the warning
}
//Instead of this, we give the caller the callback
const useCustomEffect = (knownDep) => {
const doSomething = useCallback((knownDep) => {/**/}, [])
useEffect(() => {
doSomething(knownDep)
}, [doSomething, knownDep]) // no more warning
return { doSomething }
}
// Use it like this
const { doSomething } = useCustomEffect(foo)
useEffect(doSomething, [bar, baz]) // now I can use my callback for any known dependency
如果你想提供 extra-deps,你可以使用 useDeepCompareEffect
而不是 useEffect
。
您定义自定义挂钩的方式对我来说很有意义。我无法找到任何关于执行此操作的官方方法的文档,所以现在我的解决方案是禁用规则:
function useCustomHook(param1, extraDeps) {
useEffect(() => {
// do something with param1 here
}, [param1, ...extraDeps]) // eslint-disable-line react-hooks/exhaustive-deps
}
我找到了一个有用的替代方案来替代这里提出的解决方案。如前所述 in this Reddit topic,React 团队显然推荐如下内容:
// Pass the callback as a dep
cost useCustomHook = callback => {
useEffect(() => { /* do something */ }, [callback])
};
// Then the user wraps the callback in `useMemo` to avoid running the effect too often
// Whenever the deps change, useMemo will ensure that the callback changes, which will cause effect to re-run
useCustomHook(
useMemo(() => { /* do something }, [a, b, c])
);
我已经使用过这种技术并且效果很好。
我正在创建一个自定义挂钩并想定义一个可选参数,以便我可以在需要时传入额外的依赖项。我的代码类似于以下代码段:
import { useEffect } from 'react';
function useCustomHook(param1, extraDeps) {
useEffect(() => {
// do something with param1 here
}, [param1, ...extraDeps])
}
react-hooks/exhaustive-deps 发出警告
React Hook useEffect has a spread element in its dependency array. This means we can't statically verify whether you've passed the correct dependencies
有人知道如何解决该警告吗?或者将 deps 数组传递给自定义挂钩不是一个好习惯?
对于那些对为什么需要 extraDeps 感兴趣的人。这是一个例子:
const NewComponent = (props) => {
[field1, setField1] = useState()
[field2, setField2] = useState()
// I only want this to be called when field1 change
useCustomHook('.css-selector', [field1]);
return <div>{field1}{field2}</div>;
}
您可以这样做:
将状态移动到您的自定义挂钩,运行 对其产生影响并 return 它。
类似于:
Component.js
function Component() {
const [field,setField] = useCustomHook(someProps);
}
useCustomHook.js
import {useState, useEffect} from 'react';
function useCustomHook(props) {
const [field,setField] = useState('');
useEffect(()=>{
// Use props received and perform effect after changes in field 1
},[field1]);
return([
field,
setField
]);
}
我认为问题在于您如何在自定义挂钩上创建依赖项数组。每次你这样做 [param1, ... extraDeps]
你都在创建一个新数组,所以 React 总是将它们视为不同的。
尝试将自定义挂钩更改为:
function useCustomHook(deps) {
useEffect(() => {
// do something with param1 here
}, deps)
}
然后像
一样使用它const NewComponent = (props) => {
[field1, setField1] = useState()
[field2, setField2] = useState()
// I only want this to be called when field1 change
useCustomHook(['.css-selector', field1]);
return <div>{field1}{field2}</div>;
}
希望对您有所帮助!
我遇到了类似的问题,我希望在某些额外的依赖项发生更改时执行效果。
我没有设法提供这些额外的依赖关系,而是通过向调用者提供我希望执行的回调 并让他在需要时使用它来绕过 。
示例:
// This hook uses extraDeps unknown by EsLint which causes a warning
const useCustomEffect = (knowDep, extraDeps) => {
const doSomething = useCallback((knownDep) => {/**/}, [])
useEffect(() => {
doSomething(knownDep)
}, [doSomething, knownDep, ...extraDeps]) // Here there is the warning
}
//Instead of this, we give the caller the callback
const useCustomEffect = (knownDep) => {
const doSomething = useCallback((knownDep) => {/**/}, [])
useEffect(() => {
doSomething(knownDep)
}, [doSomething, knownDep]) // no more warning
return { doSomething }
}
// Use it like this
const { doSomething } = useCustomEffect(foo)
useEffect(doSomething, [bar, baz]) // now I can use my callback for any known dependency
如果你想提供 extra-deps,你可以使用 useDeepCompareEffect
而不是 useEffect
。
您定义自定义挂钩的方式对我来说很有意义。我无法找到任何关于执行此操作的官方方法的文档,所以现在我的解决方案是禁用规则:
function useCustomHook(param1, extraDeps) {
useEffect(() => {
// do something with param1 here
}, [param1, ...extraDeps]) // eslint-disable-line react-hooks/exhaustive-deps
}
我找到了一个有用的替代方案来替代这里提出的解决方案。如前所述 in this Reddit topic,React 团队显然推荐如下内容:
// Pass the callback as a dep
cost useCustomHook = callback => {
useEffect(() => { /* do something */ }, [callback])
};
// Then the user wraps the callback in `useMemo` to avoid running the effect too often
// Whenever the deps change, useMemo will ensure that the callback changes, which will cause effect to re-run
useCustomHook(
useMemo(() => { /* do something }, [a, b, c])
);
我已经使用过这种技术并且效果很好。