Javascript React hook-useffect缺少依赖项警告

Javascript React hook-useffect缺少依赖项警告,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,通过在依赖项数组周围使用useffect,我不确定这是否是一个有效的警告,似乎每当useffect中的变量、方法或分派发出警告时 React Hook useffect缺少依赖项:“活动”、“检索用户”和“调度”。如果我只是将其保留为空白数组以执行componentDidMount功能,则可以包含它们或删除下面示例中的依赖项数组 useffect(()=>{ 设置活动(活动); 等待检索用户(param1,param2); 派遣(行动); }, []). // 警告:React H

通过在依赖项数组周围使用
useffect
,我不确定这是否是一个有效的警告,似乎每当
useffect
中的变量、方法或分派发出警告时 React Hook useffect缺少依赖项:“活动”、“检索用户”和“调度”。如果我只是将其保留为空白数组以执行
componentDidMount
功能,则可以包含它们或删除下面示例中的依赖项数组

useffect(()=>{
设置活动(活动);
等待检索用户(param1,param2);
派遣(行动);
}, []).        // 警告:React Hook useEffect缺少依赖项:“active”、“retrieveUser”、“param1”、“param2”和“dispatch”。要么包含它们,要么删除依赖项数组,但这里我只想执行componentDidMount概念,所以依赖项列表必须为空

useffect(()=>{
等待检索用户(param1,param2);
派遣(行动);
},[userId])。//警告:React Hook useEffect缺少依赖项:“retrieveUser”、“param1”、“param2”和“dispatch”。包括它们或删除依赖项数组

这些警告有效吗?特别是我只想监视特定的数据字段,如果我不能向依赖项列表(对于componentDidMOunt)添加任何内容,或者我只想监视
userId
,而不是
param1
param2
,那么将所有内部分派或方法添加到依赖项数组中有什么意义呢,etc

React发出此警告是因为您正在
useffect
中使用组件的部分状态或道具,但告诉它在该状态/道具更改时不要运行
useffect
回调。React假设只要引用的状态发生更改,您就会希望运行该
useffect()
,因此它会向您发出警告如果仅引用状态或道具之外的变量,则不会收到此警告。有关有条件运行
useffect
的信息,请参阅下文

由于您的目标是只在某些时候运行
useffect
,因此您可能需要重新构造组件,以便不同的数据处于或不处于状态。在不了解更多组件的情况下,很难推荐更具体的解决方案;但是,一个好的目标是让您在
useffect
中使用的状态与您想要触发重新渲染的更改相匹配

组件中的状态可能存在其他问题。例如,我注意到您调用
setActive(active)。如果“活动”是零部件状态的一部分,则表示您正在将“活动”设置为自身。这是不必要的。(这是假设您遵循典型的命名模式,并且可能在组件顶部有一条线,如:

const[active,setActive]=useState(initialValue);


有条件地运行
useffect

当您为
useffect()
提供第二个参数时,它会限制useffect在重新渲染器上运行回调函数的情况。这是出于性能原因,如中所述

在第一个
useffect
中,您提供了一个空数组,告诉React在组件装载和卸载时只运行那些操作(
setActive(active)
…等)

在第二个
useffect
中,您提供了一个带有
userId
的数组,告诉React仅在装载、卸载以及每当
userId
更改时运行回调


React会向您发出该警告,因为它知道如果
active
…etc或其他值更改,它将不会运行useEffect。这可能会导致组件的不同部分引用不同的状态。例如,组件的一部分可能使用
userId=1
,而另一部分使用
userId=2
。这不是React的设计工作方式。

创建一个只执行一次的钩子:

const useEffectOnce = effect => {
    useEffect(effect, []);
};
在组件内部使用此挂钩

useEffectOnce(() => {
    const request = async () => {
        const result = await retrieveSum(param1, param2);
        setResult(result);
    };

    request();
});
现在,即使你的道具(param1,param2)改变了,效果也只会被调用一次。执行此操作时要非常小心,除非你最初的道具真的很特别,否则组件可能有问题。我看不出这与禁用规则有什么不同

// eslint-disable-next-line react-hooks/exhaustive-deps

演示:

添加那些不会更改的函数(如dispatch)有什么关系?dispatch很好,但将方法添加到依赖项列表会让我感到困惑,一旦我这样做,我现有的方法会有另一个警告,建议使用useCallback…如果我的方法包含一些其他参数,例如
Wait retrieveUser(参数1、参数2、参数3)
它还建议将
param1、param2、param3
添加到依赖项列表中,但我只想观察
userId
是否更改,是否
param1
更改不应触发UseEffect如果在组件装载时只想从API检索一个userId怎么办?您可以更改userId属性,但不可以I don’我不想每次都自动发出请求。这听起来好像组件有问题,但可能存在一些有效的用例,可以只使用初始道具或状态运行一次副作用。很抱歉,我在这里不理解……正如您已经提到的,如果我删除依赖项列表,useEffect将在每次重新渲染时触发如果状态值发生任何更改,我不希望看到这种情况……我希望我的useEffect仅在某些componentDidMount(使用空数组)或componentDidUpdate/shoudUpdate(使用数组中的字段)上运行,我的问题是,基于我已有的尝试,为什么它会发出警告,我如何解决这个问题?例如,如果我没有在数组中放入任何内容来执行componentDidMount,为什么它会给时间让我添加到列表中?明白了,这就是为什么React会抛出该警告。如果变量(如
活动