【问题标题】:I have 2 states, but both are updating even though I only setState one of them我有 2 个状态,但即使我只 setState 其中一个,它们都在更新
【发布时间】:2021-01-25 05:29:39
【问题描述】:

问题

使用 React,我吃了一顿饭,里面有很多配料

const [meal, setMeal] = useState()

    meal = {
      foo: ,
      bar: ,
      ingredients: [
        id:
        name:
      ]
    }

我还需要编辑成分名称,所以我有一个不同的状态来跟踪它。我已经使用了扩展运算符。

[changeIngredients, setChangeIngredients] = useState();
// 在单独的 useEffect 中
setChangeIngredients([...meal.ingredients])

当我更新changeIngredients 时问题就开始了

  handleEdit = (e) => {
    let temp = [...changeIngredients];
    temp[e.positionOfArray].name = Number(e.target.value);
    setChangeIngredients(temp);
  };

我发现meal.ingredients 也已更新,因此无法进行比较以查看是否有任何更改。

我之前尝试将 setChangeIngredients 与 API 调用中的 response.data 结合使用,但结果相同。

setMeal(response.data)
setChangeIngredients([...response.data.ingredients])


任何意见或建议将不胜感激

【问题讨论】:

  • 您好 :) 您能否在 codesandbox 上提供一个工作示例
  • 试试这个:setChangeIngredients(prevState => ({...prevState, ...temp}))
  • 更有兴趣看看你的useEffect
  • 感谢大家的帮助。易舟的回答就是解决办法。我没有考虑到数组中有更多我必须克隆的对象。

标签: javascript reactjs


【解决方案1】:

那是因为你在同一个对象上发生了变异,这个setChangeIngredients([...meal.ingredients])里面的每个对象仍然指向ingredients的同一个引用

基本上,您需要先在初始setChangeIngredients 上克隆meal.ingredients 的副本

const sourceArray = meal.ingredients;
const clonedArray = sourceArray.map(item => ({...item}));
setChangeIngredients(clonedArray)

有关不可变https://dev.to/antonio_pangall/best-practices-to-keep-objects-and-arrays-immutable-in-javascript-3nmm的更多信息,请查看此处

【讨论】:

  • 非常感谢!这正是问题所在。我一直尝试在不同的变量上使用spread,但没有考虑到数组也充满了对象。
【解决方案2】:

正如here 所提到的,扩展运算符只进行浅拷贝。它只克隆主对象...属性的副本仍将通过引用传递。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-30
    • 2020-01-19
    • 2019-03-28
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 2020-09-10
    • 2018-08-05
    相关资源
    最近更新 更多