Javascript 为什么是状态变量';当通过道具传入时,需要将s setter作为具有useEffect的依赖项?

Javascript 为什么是状态变量';当通过道具传入时,需要将s setter作为具有useEffect的依赖项?,javascript,reactjs,use-effect,Javascript,Reactjs,Use Effect,比较以下两个组件: Child.js import React, { useEffect } from "react"; function Child({ count, setCount }) { // Note: Has parameter useEffect(() => { setInterval(() => { setCount(prevCount => prevCount + 1); }, 1000); }, []); ret

比较以下两个组件:

Child.js

import React, { useEffect } from "react";

function Child({ count, setCount }) { // Note: Has parameter
  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }, []);

  return <div>{count}</div>;
}

export default Child;
import React, { useEffect, useState } from "react";

function Child2() { // Note: No parameter
  const [count, setCount] = useState(0); // State variable assigned in component

  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }, []);

  return <div>{count}</div>;
}

export default Child2;
import React,{useffect}来自“React”;
函数子级({count,setCount}){//注意:有参数
useffect(()=>{
设置间隔(()=>{
setCount(prevCount=>prevCount+1);
}, 1000);
}, []);
返回{count};
}
导出默认子对象;
Child2.js

import React, { useEffect } from "react";

function Child({ count, setCount }) { // Note: Has parameter
  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }, []);

  return <div>{count}</div>;
}

export default Child;
import React, { useEffect, useState } from "react";

function Child2() { // Note: No parameter
  const [count, setCount] = useState(0); // State variable assigned in component

  useEffect(() => {
    setInterval(() => {
      setCount(prevCount => prevCount + 1);
    }, 1000);
  }, []);

  return <div>{count}</div>;
}

export default Child2;
import React,{useffect,useState}来自“React”;
函数Child2(){//注意:没有参数
const[count,setCount]=useState(0);//在组件中分配的状态变量
useffect(()=>{
设置间隔(()=>{
setCount(prevCount=>prevCount+1);
}, 1000);
}, []);
返回{count};
}
导出默认的Child2;
它们本质上是一样的。两者之间的区别在于Child.js获取状态变量
count
及其setter
setCount
,而Child2.js设置该状态变量本身

它们都工作得很好,但是Child.js(和only Child.js)抱怨“缺少依赖项:'setCount.”将
setCount
添加到依赖项数组会消除警告,但我正在试图弄清楚为什么需要这样做。为什么
Child
中需要依赖项,而
Child2
中不需要依赖项


我有工作的例子

ESLint规则在确定哪些内容可能会更改,哪些内容可能不会更改方面并不十分智能,因此会提示您传递useEffect函数回调中使用的每个变量,以便您不会意外错过这些更改

由于钩子严重依赖于闭包,初学者发现调试闭包相关的问题很困难,因此这里的eslint警告可以很好地帮助避免此类情况

现在,由于状态更新程序直接从useState返回,并且在组件生命周期中不会更改,因此可以避免将其作为依赖项传递,并禁用类似的警告

useEffect(() => {
   setInterval(() => {
      setCount(prevCount => prevCount + 1);
   }, 1000);
   // eslint-disable-next-line react-hooks/exhaustive-deps
}, []) 

来自prop的setter函数可能会更改并过时,并且由于闭包,useEffect可能会调用错误的setter函数。Child2组件没有抱怨,因为setter函数是在组件内部声明的,因此setter函数是稳定的,不会过时。这就是为什么Child2不抱怨,但Child2抱怨。