在Redux中更改状态

汤姆兹

我正在尝试向中的数组添加元素,state并更改另一个数组元素的属性。假设我们具有以下state结构:

{
  menuItems: [{
    href: '/',
    active: true
  }]
}

分派ADD_MENU_ITEM动作后,我想结束此操作state

{
  menuItems: [{
    href: '/new',
    active: true
  }, {
    href: '/',
    active: false,
  }]
}

我尝试以几种方式在Redux减速器管理此问题

function reducer(state = {}, action) {
  switch (action.type) {
    case ADD_MENU_ITEM: {
      let menuItems = state.menuItems;
      let newMenuItem = action.newMenuItem; 

      // First try
      menuItems[0].active = false;
      menuItems.unshift(newMenuItem);
      state = Object.assign({}, state, { menuItems: menuItems });

      // Second try 
      menuItems[0].active = false;
      menuItems.unshift(newMenuItem);
      state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});

      // Third try 
      menuItems[0].active = false;
      state = (Object.assign({}, state, {
        menuItems: [
          Object.assign({}, newMenuItem), 
          ...menuItems
        ]
      }));

      // Fourth try
      menuItems[0].active = false;
      state = update(state, {
        menuItems: {$unshift: new Array(newMenuItem)}
      });

      console.log(state);
      return state;
    }
  }
}

在第四次尝试中,我正在使用React的Immutability Helpers,但是它永远无法正常工作。我在返回状态之前已将状态记录到控制台,并且它已正确记录,但是在内部记录重新获取的组件时rendered,即使该active成员设置为,menuItems数组也不会添加第一项false

我可能做错了什么?

DDA

减速器中的状态应该是不变的,因此不应修改。还建议尽可能平整对象。

在您的方案中,您的初始状态可能是这样的数组:

[{
    href: '/',
    active: true
  }]

在您的reducer中,尝试返回一个全新的数组,如下所示:

function reducer(state = {}, action) {
  switch (action.type) {
    case ADD_MENU_ITEM: {
      return [
        action.newMenuItem,
        ...state.map(item => Object.assign({}, item, { active: false }))
      ];
    }
  }
}

有关减速器的更多信息,请参见:Redux减速器文档

文档中的有用摘录:

减速器保持纯净非常重要。在减速器中永远不应该做的事情:

  • 改变其论点;
  • 执行副作用,例如API调用和路由转换;
  • 调用非纯函数,例如Date.now()或Math.random()。

添加了更多信息

在您的化简器中,对于所有四次尝试,您都在修改现有状态之前将其返回。

react-redux当检查您的状态是否已更改时,结果为,因为上一个和下一个状态都指向同一对象,所以看不到任何更改。

这是我指的行:

第一次尝试:

  // This line modifies the existing state.
  state = Object.assign({}, state, { menuItems: menuItems });

第二次尝试:

  // This line modifies the existing state.
  state = Object.assign({}, state, {menuItems: Object.assign([], menuItems)});

第三次尝试:

  // This line modifies the existing state.
  state = (Object.assign({}, state, {
    menuItems: [
      Object.assign({}, newMenuItem), 
      ...menuItems
    ]
  }));

第四次尝试:

  // This line modifies the existing state.
  state = update(state, {
    menuItems: {$unshift: new Array(newMenuItem)}
  });

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章