首页 > 解决方案 > 我在reducer中改变redux状态吗?

问题描述

我正在尝试使用减速器在我的状态下更改数组中的一项。

状态如下:

state: {
  items: [
  {
    id: 1,
    name: 'Superman',
    wearsCape: true
  },
  {
    id: 2,
    name: 'Batman',
    wearsCape: true
  },
  {
    id: 3,
    name: 'Iron Man',
    wearsCape: false
  }
];
}

我正在尝试过滤状态中的所有项目以搜索名称为 equal 的超级英雄的首次出现sHero.name。然后我试图改变找到的超级英雄的属性。减速器代码如下所示:

function findCapedCrusader(state, { sHero }) {
  var result = state.items.filter(s => {
    return s.name === sHero.name;
  });

  result[0].wearsCape = false;

  return { ...state };

}

我是否通过执行上述操作来改变状态?

注意:为愚蠢的例子道歉。我是反应和减少的新手。

标签: javascriptreactjsreduximmutability

解决方案


据我所知,filter方法返回一个新数组,但返回的元素仍然引用旧的。因此,如果有人将属性更改为新创建的数组,他们也会更改原始数组。

const state = {
  items: [
  {
    id: 1,
    name: 'Superman',
    wearsCape: true
  },
  {
    id: 2,
    name: 'Batman',
    wearsCape: true
  },
  {
    id: 3,
    name: 'Iron Man',
    wearsCape: false
  }
]
};

const newItem = state.items.filter( s => s.name === "Superman");

newItem[0].wearsCape = false;

console.log( "newitem", newItem, "\noriginal", state.items[0] );

如果您想更改数组中一个对象的属性并更新您的状态:

const state = {
  items: [
  {
    id: 1,
    name: 'Superman',
    wearsCape: true
  },
  {
    id: 2,
    name: 'Batman',
    wearsCape: true
  },
  {
    id: 3,
    name: 'Iron Man',
    wearsCape: false
  }
]
};

const newItems = state.items.map( s => {
  if( s.name === "Superman") {
    return { ...s, wearsCape: false };
  }
  return s;
});

console.log( "new items", newItems, "original", state.items );

如您所见,原始items文件没有发生变异。对于您的情况,它将是这样的:

function findCapedCrusader(state, { sHero }) {
  var newItems = state.items.map(s => {
    if (s.name === sHero.name ) {
        return { ...s, wearsCape = false }
    }
    return s;
  });
  return { ...state, items: newItems };
}

同样,此函数将更改一个对象的属性,而不会更改其他任何内容。我不太确定这是你想要的,因为你正在尝试filter你的问题。如果你想用一个对象更新你的状态,我可以建议另一种解决方案。


推荐阅读