【问题标题】:keeping reference between two states in React在 React 中保持两个状态之间的引用
【发布时间】:2022-11-02 20:29:42
【问题描述】:

我试图在两种状态之间保持引用,一种是对象数组,第二种是数组中对象的哈希表。

香草 javascript 示例:

const state1 = [{id: 1, name: 'foo'}];
const state2 = state1[0];

现在,我想更改 state2 中会影响 state1 的值。

state2.name = "bar";
console.log(state1) // output:  [{id: 1, name: 'bar'}]
console.log(state2) // output:  {id: 1, name: 'bar'}

我该怎么做才能做出反应? 任何国家都有他自己的参考。

谢谢!

const [state1, setState1] = useState([]);
const [state2, setState2] = useState({});

setState1([{id: 1, name: 'foo'}]);
setState2(state1[0]);
console.log(state1) // output:  [{id: 1, name: 'foo'}]
console.log(state2) // output:  {id: 1, name: 'foo'}


setState2((prevState) => {
    return {
      ...prevState,
      name: "bar"
    };
  });

console.log(state1) // output:  [{id: 1, name: 'foo'}]
console.log(state2) // output:  {id: 1, name: 'bar'}

【问题讨论】:

  • 乍一看,通常的答案是“你不知道”。为什么需要在多个地方复制相同的状态?如果您需要的是对state1 的引用,那么为什么不能使用state1?这有什么用例?
  • 顺便说一句......显示的代码根本不会产生显示的输出。状态更新是异步的。如果您在更新后立即将状态记录到控制台,那么您将看不到这些更新。听起来您正在做出一些错误的假设,这些假设会使您的调试蒙上阴影。
  • 假设我有一个对象数组,并且任何对象都有嵌套对象。我不想使用嵌套循环来获取特定对象。我希望能够通过 O(1) 按键获取对象。
  • 对象没有“循环”。对象只是数据。您可以通过索引引用数组,可以使用findfilter 等操作搜索项目。目前尚不清楚为什么要或需要复制您的状态。但是,如果你真的很想要复制状态,然后在更新state1 之后,您将更新state2。在显示的示例中,您只更新其中一个。
  • 我不想手动更新两个状态!我想更新一种会影响第二种状态的状态。是的,我可以使用 for..in 循环循环对象,但我不想使用它。将此代码粘贴到您的控制台中: const state1 = [{id: 1, name: 'foo'}];常量 state2 = state1[0]; state2.name = "酒吧";在我只更改 state2 名称后,让我知道 state1 名称发生了什么。

标签: reactjs


【解决方案1】:

你没有。

您的原始 JavaScript 代码“工作”的唯一原因是因为您依赖于对内存中对象的引用并改变了这些对象。在 React 中,你不会改变状态。由于更新状态会创建一个新引用,因此您需要复制更新以涵盖两个状态值。

但更重要的是...

这里不需要复制状态。而且,正如你所发现的,当你重复数据那么你还需要重复逻辑手动保持该数据同步。例如,这里您只更新state2

setState2((prevState) => {
  return {
    ...prevState,
    name: "bar"
  };
});

所以只有state2 得到更新。如果您还希望更新state1,则需要更新state1。例如:

setState1((prevState) => {
  return prevState.map((p, i) => {
    if (i === 0) { // the same magic value you already use
      return {
        ...p,
        name: "bar"
      };
    } else {
      return p;
    }
  });
});

在组件的其他地方,响应该状态更新:

useEffect(() => {
  setState2(state1[0]); // here's that magic value again
}, [state1, setState2]);

而这个额外的操作是为了……什么目的?因此,您可以方便地在代码中引用 state2 而不是引用 state1[0]?似乎是不必要的工作/复杂性,回报很少。

只是不要复制您的状态/数据/参考/等。首先,问题变得没有实际意义。维护您的记录系统(或事实来源,如果您愿意)并使用该数据。手动保持多个数据源同步是 (1) 困难且 (2) 不必要的。

如果你真的想要在两个状态值中具有相同的数据,然后如上所述,您只需添加一个 useEffect 以在另一个更新时更新一个。但请注意,这种额外的复杂性可能会导致未来的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 2019-07-24
    相关资源
    最近更新 更多