当前位置:  开发笔记 > 编程语言 > 正文

在Redux中改变状态

如何解决《在Redux中改变状态》经验,为你挑选了1个好方法。

我试图在一个数组中添加一个元素state并更改另一个数组元素的属性.假设我们有以下state结构:

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

在调度ADD_MENU_ITEM动作之后,我想最终得到这个state:

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

我尝试过几种方式在Redux Reducer中管理它:

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,该阵列的MenuItems不添加的第一个项目,虽然active成员设置为false.

我能做错什么?



1> DDA..:

reducer中的状态应该是不可变的,因此不应该修改.还建议尽可能展平您的物体.

在您的场景中,您的初始状态可能是一个数组:

[{
    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 }))
      ];
    }
  }
}

有关Reducer的更多信息,请访问:Redux Reducers文档

文档的有用摘录:

减速机保持纯净非常重要.你应该在减速机内做的事情:

改变其论点;

执行API调用和路由转换等副作用;

调用非纯函数,例如Date.now()或Math.random().

更多信息已添加

在您的reducer和所有四次尝试中,您在返回之前修改现有状态.

这会导致在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)}
  });

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有