当前位置: 首页 > 知识库问答 >
问题:

仅在两个依赖项都更改时运行效果挂接

公西修文
2023-03-14

我有一个React组件,它使用useffect钩子获取数据,如下所示:

const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
    const [data, setData] = useState();
    useEffect(() => {
        const fetchedData; // fetch data using key and options
        setData(fetchedData);
        cache[key] = fetchedData;
    }, [key, options])
    return <p>{data}</p>;
}

每次选项更改时,都会运行钩子。但是,我也在本地缓存数据,并且只希望在选项都更改时运行效果(因为对于每个键/选项组合,数据总是相同的)。

是否有一种干净的方法来依赖于选项的组合,而不是使用React钩子的选项

共有3个答案

公良扬
2023-03-14

所有提供的解决方案都很好,但是有一些更复杂的情况,例如,当使用效果函数应该只在依赖关系A和B改变时调用,而它也取决于C的值。

所以我建议使用useffects序列和中间状态为未来的逻辑提供更多的空间。针对被问问题的这一方法的实施将是:

const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
    const [data, setData] = useState();

    const [needsUpdate, setNeedsUpdate] = useState(()=>({key:false, option:false}));

    useEffect(()=>{
      setNeedsUpdate((needsUpdate)=>({...needsUpdate, key:true}));
    },[key])

    useEffect(()=>{
      setNeedsUpdate((needsUpdate)=>({...needsUpdate, options:true}));
    },[options])

    useEffect(() => {
      if (needsUpdate.key && needsUpdate.options){
        const fetchedData; // fetch data using key and options
        setData(fetchedData);
        cache[key] = fetchedData;
        setNeedsUpdate(()=>({key:false, option:false}));
      }
    }, [needsUpdate, key, options])
    return <p>{data}</p>;
}

通过这种方式,我们可以在useEffect依赖项上应用几乎任何逻辑,但是它有自己的缺点,即渲染周期很少。

东方灵均
2023-03-14

为了在两个值都更改时运行效果,您需要使用以前的值,并在关键点或选项更改时在挂钩内比较它们。

您可以编写一个usePrevioushook,并将旧状态和以前的状态进行比较,如本文所述:

如何在效果上比较旧值和新值?

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

const cache = {key: "data-fetched-using-key"}
function Config({key, options}) {
    const [data, setData] = useState();
    const previous = usePrevious({key, options});
    useEffect(() => {
        if(previous.key !== key && previous.options !== options) {
            const fetchedData; // fetch data using key and options
            setData(fetchedData);
            cache[key] = fetchedData;
        }
    }, [key, options])
    return <p>{data}</p>;
}
公西嘉玉
2023-03-14

您可以使用useRef()创建这种逻辑。考虑以下示例和沙盒:https://codesandbox.io/s/react-hooks-useeffect-with-multiple-reqs-6ece5

const App = () => {
  const [name, setName] = useState();
  const [age, setAge] = useState();

  const previousValues = useRef({ name, age });

  useEffect(() => {
    if (
      previousValues.current.name !== name &&
      previousValues.current.age !== age
    ) {
      //your logic here
      console.log(name + " " + age);
      console.log(previousValues.current);

      //then update the previousValues to be the current values
      previousValues.current = { name, age };
    }
  });

  return (
    <div>
      <input
        placeholder="name"
        value={name}
        onChange={e => setName(e.target.value)}
      />
      <input
        placeholder="age"
        value={age}
        onChange={e => setAge(e.target.value)}
      />
    </div>
  );
};

工作流程:

  1. 我们为要跟踪的两个值创建一个ref对象,在本例中,它是nameage。ref对象是previousValues
  2. useffect已定义,但我们不提供任何依赖项。相反,只要状态更改为nameage,我们就让它执行
  3. 现在在useffect中,我们有条件逻辑来检查nameage的先前值/初始值是否与其对应的状态值不同。如果它们很好,我们就执行逻辑(console.log)
  4. 最后,在执行逻辑后,将ref对象(以前的值)更新为当前值(状态)
 类似资料:
  • 当前,只有一个依赖项发生更改时,才会触发。 当两个(或所有)依赖项都已更改时,我如何更新/使用它进行回击?

  • 但是,这样做的缺点是将报告为未使用,可能是因为编译不需要它: 我不能使用依赖项,因为我不希望该依赖项传递性地继承(例如,下游依赖项可以使用log4j等)。我使用尝试了,但结果是相同的警告。 (注意,我还可以为依赖插件设置,但这似乎是一个非常生硬的工具,会隐藏其他潜在的问题。)

  • 在Java10和maven中运行我的Spring boot项目,一切都很好。简单地将JDK从10更改为11会导致以下错误: 我没有使用Spring Webflux框架,以前也不需要任何带有reactor框架的jar。我知道Java 11从JDK中剔除了很多JEE的东西,但这不是那个。 我尝试了SpringBoot 2.0.5版本和最新的里程碑版本(M4)2.1,结果是一样的。我已经更改了Finch

  • 在Synfony 3.3中,DI的新最佳实践 是使用普通构造函数依赖项注入(或控制器中的“操作”注入),而不是通过$this获取公共服务- 如官方留档所见 因此,无需指定服务,因为我们可以在类控制器中键入提示: 这似乎工作得很好,但如果我扩展了一个类并在构造函数中添加了更多参数呢??? 现在我得到一个循环引用错误: [Symfony\Component\DependencyInjection\Ex

  • 是否可能在运行时检索特定maven依赖项的版本? 例如。对于pom.xml: 我想检索具有工件ID的特定依赖项的版本。

  • 我创建了一个Maven项目(可重用库),该项目有许多依赖项(编译时和运行时),它们也可以过渡地依赖于其他许多依赖项。在maven中,我可以在pom中添加依赖项。xml及其可传递依赖关系将自动处理。所以,我将毫无问题地运行。 现在,我有一个非Maven(基于Ant的)项目,上面创建的库(Maven Lib)将使用它。 在这种情况下,运行时间