Reactjs 如何在使用其他变量的同时,仅对React中更改的1个变量使用listen?

Reactjs 如何在使用其他变量的同时,仅对React中更改的1个变量使用listen?,reactjs,react-hooks,use-effect,Reactjs,React Hooks,Use Effect,我正试图用功能反应来建立我的(爱好)网站。在那里,我多次遇到以下情况: const[randomData,setRandomData]=useState(true); const[activePopup,setActivePopup]=useState(1); useffect(()=>{ ... 控制台日志(随机数据); },[activePopup]) (为了清楚起见,这是一个虚构的例子) 我试图实现useffect块中的代码在activePopup更改时运行,并且只有在更改之后,我还需要

我正试图用功能反应来建立我的(爱好)网站。在那里,我多次遇到以下情况:

const[randomData,setRandomData]=useState(true);
const[activePopup,setActivePopup]=useState(1);
useffect(()=>{
...
控制台日志(随机数据);
},[activePopup])
(为了清楚起见,这是一个虚构的例子)

我试图实现
useffect
块中的代码在
activePopup
更改时运行,并且只有在更改之后,我还需要访问其他属性和状态。在VS代码中,这会导致一个警告,指出钩子缺少依赖项,应该添加这些依赖项,或者删除依赖项数组

理论上,我明白了为什么
useffect
需要依赖项数组中的所有变量:如果
randomData
更改而没有
activePopup
更改,那么这个
useffect
调用将不会运行。但是如果它不需要,我只需要在打开弹出窗口时访问它怎么办

我知道这样的问题通常意味着代码的结构不好,但是对于“我只想在打开弹出窗口时知道/处理变量X的值”这样的情况,我真的想不出将变量X包含在依赖项数组中的理由。也许
useffect
不是处理这个问题的正确方法,我想有些人会建议在打开弹出窗口的同一个位置使用变量,但是考虑到使用了一些上下文,只需监听
activePopup
值上的更改就简单多了,更容易阅读

randomData
从依赖项数组中移出并忽略警告可以吗?是否有不同的方式来响应变量的变化?我如何处理这种情况

简化的
如果
activePopup
changes=>使用
randomData


随机数据
发生变化时,不要运行相同的代码。

如果没有更多细节,很难给出适用于此场景中所有可能情况的答案,但要点是否定的,解决任何特定问题都不需要违反详尽的deps规则

最简单的技巧之一是应用,以确保不会从过时的闭包访问
randomData

const [randomData, setRandomData] = useState(true);
const [activePopup, setActivePopup] = useState(1);

const randomDataRef = useRef();

useEffect(() => {
  randomDataRef.current = randomData;
}, [randomData]);

useEffect(() => {
    // log randomData only when activePopup changes
    console.log(randomDataRef.current);
}, [activePopup]);
这是因为调用
useRef()
的返回值不受详尽的deps规则的约束。无论它是否在数组中,行为都不会改变,其引用也不会因设计而过时。由于React正在记忆
randomDataRef
,因此这与上述内容完全相同:

const [randomData, setRandomData] = useState(true);
const [activePopup, setActivePopup] = useState(1);

const randomDataRef = useRef();

useEffect(() => {
  randomDataRef.current = randomData;
}, [randomData, randomDataRef]);
//              ^~~~~~~~~~~~~

useEffect(() => {
    // log randomData only when activePopup changes
    console.log(randomDataRef.current);
}, [activePopup, randomDataRef]);
//               ^~~~~~~~~~~~~

对于记录,同样的推理适用于为什么
useState()
返回的setter和
useReducer()中的dispatch函数也不受详尽的deps规则的约束;它们都由React记忆,因此将它们包含在依赖项数组中或从依赖项数组中省略它们对
useffect()

的行为没有任何影响,没有更多细节,很难给出适用于此场景所有可能情况的答案,但要点是否定的,解决任何具体问题都不需要违反详尽的deps规则

最简单的技巧之一是应用,以确保不会从过时的闭包访问
randomData

const [randomData, setRandomData] = useState(true);
const [activePopup, setActivePopup] = useState(1);

const randomDataRef = useRef();

useEffect(() => {
  randomDataRef.current = randomData;
}, [randomData]);

useEffect(() => {
    // log randomData only when activePopup changes
    console.log(randomDataRef.current);
}, [activePopup]);
这是因为调用
useRef()
的返回值不受详尽的deps规则的约束。无论它是否在数组中,行为都不会改变,其引用也不会因设计而过时。由于React正在记忆
randomDataRef
,因此这与上述内容完全相同:

const [randomData, setRandomData] = useState(true);
const [activePopup, setActivePopup] = useState(1);

const randomDataRef = useRef();

useEffect(() => {
  randomDataRef.current = randomData;
}, [randomData, randomDataRef]);
//              ^~~~~~~~~~~~~

useEffect(() => {
    // log randomData only when activePopup changes
    console.log(randomDataRef.current);
}, [activePopup, randomDataRef]);
//               ^~~~~~~~~~~~~

对于记录,同样的推理适用于为什么
useState()
返回的setter和
useReducer()中的dispatch函数也不受详尽的deps规则的约束;它们都由React进行记忆,因此将它们包含在依赖项数组中或从依赖项数组中省略它们对
useffect()

将其添加到依赖项数组并使用
if(activePopup)的行为没有任何影响
在回调中,在效果中省略一个依赖项意味着在执行效果时,数据可能会过时。您可能会误解依赖关系。如果其中一个发生更改,将执行您的效果。没有必要两者都改变。请参阅以供参考。@PatrickRoberts不只是检查
activePopup
是否真实吗?在我的例子中,
activePopup
总是被设置为一个数字,所以它总是真实的。如果有办法检查是哪个变量更改导致了调用,我很想知道。@nil不,我了解依赖项,这正是我不希望依赖项数组中出现
randomData
的原因
randomData
可以随意更改,但我不希望在
randomData
更改时调用
useffect
,只需要在
activePopup
更改时调用它。我不明白
randomData
怎么会过时:据我所知,当我使用上述示例时,
randomData
useffect
中可用,就像
activePopup
更改时一样,这正是我所需要的。如果我理解正确,它只有在
useffect
运行很长时间后才会过时。为什么
activePopup
是一个数字?你在跟踪多个弹出窗口吗?将activePopup更改为布尔值,然后在
useffect
中设置一个条件,检查
activePopup===true
是否适合您的情况。您能否提供有关所需功能的更多信息?将其添加到依赖项数组,并在回调中使用
if(activePopup)
,省去一个依赖项