Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/391.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 触发仅在某些条件下有效_Javascript_Reactjs_Typescript_Use Effect - Fatal编程技术网

Javascript 触发仅在某些条件下有效

Javascript 触发仅在某些条件下有效,javascript,reactjs,typescript,use-effect,Javascript,Reactjs,Typescript,Use Effect,我对使用效果有基本的了解。如果没有第二个参数(依赖项数组),它将在每个渲染上运行。对于空数组,它在第一次渲染时运行。对于数组中的参数,它会在某些参数更改时运行 假设我有两个依赖项(来自GraphQL查询):result.data和result.load。如果result.data发生更改,并且result.load为false,我希望运行useEffect。例如,目的是更新Redux存储: useEffect(() => { if (result.loading) return;

我对使用效果有基本的了解。如果没有第二个参数(依赖项数组),它将在每个渲染上运行。对于空数组,它在第一次渲染时运行。对于数组中的参数,它会在某些参数更改时运行

假设我有两个依赖项(来自GraphQL查询):
result.data
result.load
。如果
result.data
发生更改,并且
result.load
为false,我希望运行useEffect。例如,目的是更新Redux存储:

useEffect(() => {
  if (result.loading) return;
  dispatch(updatePhotos([...photos, ...result.data.photos]));
}, [result.data, result.loading]);
但有一个陷阱:我必须在依赖项列表中包含
照片。但是,
photos
变量将在其他位置更新,并再次触发此useEffect

仅当这两个变量发生变化时,如何运行useEffect?

当然,我可以使用useState来存储变量
resultFetched
,在useffect中将它设置为
true
,然后仅当它是
false
时才进行调度。但在某些时候,我必须将其更改回
true
,并且再次运行useEffect,因为我无法手动更改
result.data
result.load

当有很多变量需要处理时,我不知道如何在这些情况下正确使用useEffect

目前,我正在构建无限滚动照片列表,其中列表通过GraphQL逐部分加载。但当用户打开一些照片并最终返回照片列表时,它将从Redux恢复到与打开照片之前相同的状态和滚动位置

我花了无数个小时试图让它工作,但这个useEffect的东西破坏了我的每一次尝试。:)它们总是在我想要它们触发之前被触发,因为有太多变化的变量

此外,有时我希望在
useffect
(添加到依赖项数组的函数)中运行函数,并使用
useCallback
对该函数进行记忆。但我还必须将函数使用的所有变量添加到
useCallback
的依赖项数组中,这样当这些变量发生变化时,函数就会重新生成。这意味着
useffect
突然再次运行,因为依赖项数组中的函数发生了变化


是否真的没有办法在
useffect
中使用函数/变量,如果没有它们来触发
useffect

这一切都取决于updatePhotos的工作方式。如果这产生了一个动作,那么问题是你在错误的地方创造了新的状态。这里不应该使用照片的前一个值,因为正如您所指出的,这会导致依赖关系

相反,您的reducer将具有您可以使用的照片的旧值,您只需将新的请求数据传递给reducer即可


此处有更详细的描述:

您可以在同一个组件中有两个单独的useEffect函数,它们将彼此独立工作。一个用于照片,一个用于数据加载。我希望这个例子能帮助你理解这一点

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

function App() {
  const [count, setCount] = useState(0);
  const [count2, setCount2] = useState(0);
  const [step, setStep] = useState(1);

  useEffect(() => {
    const id = setInterval(() => {
      setCount((c) => c + step);
    }, 1000);
    return () => clearInterval(id);
  }, [step]);

  useEffect(() => {
    const id = setInterval(() => {
      setCount2((c) => c + step);
    }, 1500);
    return () => clearInterval(id);
  }, [step]);

  return (
    <div>
      <h1>{count}</h1>
      <h1>{count2}</h1>
      <input value={step} onChange={(e) => setStep(Number(e.target.value))} />
    </div>
  );
}
ReactDOM.render(<App />, document.getElementById("container"));
import React,{useState,useffect}来自“React”;
从“react dom”导入react dom;
函数App(){
const[count,setCount]=useState(0);
const[count2,setCount2]=useState(0);
常量[步骤,设置步骤]=使用状态(1);
useffect(()=>{
常量id=setInterval(()=>{
设置计数((c)=>c+步进);
}, 1000);
return()=>clearInterval(id);
},[步骤];
useffect(()=>{
常量id=setInterval(()=>{
setCount2((c)=>c+步进);
}, 1500);
return()=>clearInterval(id);
},[步骤];
返回(
{count}
{count2}
setStep(Number(e.target.value))}/>
);
}

ReactDOM.render(

是的,你说得对。这解决了Redux的问题,谢谢:)