【问题标题】:Why doesn't a useEffect hook trigger with an object in the dependency array?为什么 useEffect 挂钩不触发依赖数组中的对象?
【发布时间】:2020-10-20 21:52:24
【问题描述】:

我在使用钩子时注意到一些非常奇怪的东西,我有以下几点:

import React, { useState, useEffect } from "react";

const [dependency1, setDependency1] = useState({});
const [dependency2, setDependency2] = useState([]);

useEffect(() => {
  console.log("dependency 1 got an update");
}, [dependency1]);

useEffect(() => {
  console.log("dependency 2 got an update");
}, [dependency2]);

setInterval(() => {
  setDependency1(prevDep1 => {
    const _key = "test_" + Math.random().toString();
    if (prevDep1[_key] === undefined) prevDep1[_key] = [];
    else prevDep1[key].push("foo");
    return prevDep1;
  })
  setDependency2(prevDep2 => [...prevDep2, Math.random()]);
}, 1000);

由于某种原因,只有dependency2 (添加项目的数组) 的 useEffect 触发,dependency1 (添加键的对象)的那个触发 不会触发..

为什么会发生这种情况,我怎样才能让它发挥作用?

【问题讨论】:

    标签: reactjs react-hooks use-effect use-state


    【解决方案1】:
    setInterval(() => {
        setDependency1(prevDep1 => {
          const _key = "test_" + Math.random().toString();
          return {...prevDep1, [_key]: [...(prevDep1[_key] || []), 'foo']   }
        })
        setDependency2(prevDep2 => [...prevDep2, Math.random()]);
      }, 1000);
    

    状态应该以不可变的方式更新。

    【讨论】:

      【解决方案2】:

      React 仅在决定依赖项更改时检查引用相等性,因此如果旧值和新值通过 === 检查,则认为它未更改。

      在您的第一个依赖项中,您只需向现有对象添加一个键,因此不会更改实际对象。当将旧值分散到新数组中时,第二个依赖项实际上会被完全替换。

      【讨论】:

      • 我更新了我的问题,所以它返回了一些东西,但它仍然不起作用..
      • 最后一段不再有效,但另一点仍然正确。只要新旧 props 通过引用相等检查 === 就不会触发更改。
      【解决方案3】:

      你在这里返回了一个赋值语句:

      setDependency1(prevDep1 => prevDep1["test_" + Math.random().toString()] = ["foo"]);
      

      你应该返回一个对象。可能是这样的:

      setDependency1(prevDep1 => ({ ...prevDep1, ["test_" + Math.random().toString()]: ["foo"] }));
      

      【讨论】:

      • 但是如果我必须使用 if 语句怎么办?
      • 删除短返回语法并像普通函数一样使用它。 (例如prevDep1 => { if (someCondition) { return someValue; } else { return otherValue; } }
      • 不幸的是也不起作用,请参阅我更新的问题..
      • 检查@Mordechai 的答案。他已经指出了问题所在。相等性检查失败,因为您每次都返回相同的对象。您可以尝试将return prevDep1 替换为return { ...prevDep1 }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-06
      • 2021-07-02
      • 1970-01-01
      • 2021-08-29
      • 2020-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多