【问题标题】:Changing state in Redux在 Redux 中更改状态
【发布时间】:2015-12-24 00:50:20
【问题描述】:

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

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

在发送ADD_MENU_ITEM 操作后,我想以这个state 结束:

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

我已经尝试在 Redux reducers 中以多种方式管理它:

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 成员设置为@ 987654332@.

我做错了什么?

【问题讨论】:

    标签: reactjs redux


    【解决方案1】:

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

    关于减速器的更多信息可以在这里找到:Redux Reducers Documentation

    来自文档的有用摘录:

    reducer 保持纯净非常重要。在 reducer 中你不应该做的事情:

    • 改变它的论点;
    • 执行 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)}
      });
    

    【讨论】:

    猜你喜欢
    • 2020-01-10
    • 2016-08-31
    • 2021-10-03
    • 1970-01-01
    • 2018-05-21
    • 2016-10-21
    • 2020-04-26
    • 1970-01-01
    • 2017-09-21
    相关资源
    最近更新 更多