繁体   English   中英

当数组尚不存在时,如何在 Redux 中的 reducer 中向数组添加元素?

[英]How do I add an element to array in reducer in Redux when the array does not yet exist?

我有一个代码沙箱来演示我在 Redux 和 React 中遇到的问题。

https://codesandbox.io/s/reactredux-3edy8

基本上这个减速器不起作用:

const initialState = {
  byId: {}
};

function addReducer(state = initialState, action) {
  switch (action.type) {
    case "RECEIVE_DATA":
      return {
        ...state,
        byId: {
          ...state.byId,
          [action.payload.id]: [
            ...state.byId[action.payload.id],
            action.payload.data
          ]
        }
      };
    default:
      return state;
  }
}

export default addReducer;

这是行动:

import { RECEIVE_DATA } from "./actionTypes";

export function action() {
  return {
    type: RECEIVE_DATA,
    payload: {
      id: Math.floor(Math.random() * 2),
      data: Math.floor(Math.random() * 10000)
    }
  };
}

在我自己的应用程序中,它会抛出一个错误,例如state.byId[action.payload.id] is not iterable 这是真的。 但是如何将值推送到一个尚不存在的数组,因为我不知道id

我认为这个问题可以通过更改initialState来解决,或者可能有一个我不知道的函数允许我创建一个arraypush送到它。

首先检查数组是否存在。 如果是,请添加一个新元素。 如果不是,则创建一个包含一个元素的新数组(来自动作的新数据)

const initialState = {
  byId: {}
};

function addReducer(state = initialState, action) {
  switch (action.type) {
    case "RECEIVE_DATA":
      return {
        ...state,
        byId: {
          ...state.byId,
          [action.payload.id]: (
              state.byId[action.payload.id] ? [
              ...state.byId[action.payload.id],
              action.payload.data
            ] : [action.payload.data])
        }
      };
    default:
      return state;
  }
}

export default addReducer;

您可以在此处阅读有关三元语句的更多信息: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

我不确定,但我认为你需要这样的东西

 function addReducer(state = initialState, action) {
      switch (action.type) {
        case "RECEIVE_DATA":
          return {
            ...state,
            byId: {
              ...state.byId,
              [action.payload.id]: 
                [action.payload.data]

            }
          };
        default:
          return state;
      }
    }

这个问题的答案在于扁平化状态。 我确信还有其他方法可以解决这个问题,但我发现这是最干净的。

通常,状态的byId属性是根据文档中的指南通过展平状态创建

我更进一步,使byId属性成为一个数组而不是一个对象。 我将id移动到数组的对象中,就像在这个新沙箱中一样: https : //codesandbox.io/s/reactredux-zj1n4

我只需要记住当我将状态映射到我的组件时byId现在是一个数组。

没有任何功能丢失,如果需要,我的byId字段现在可以支持多个不同的 id(例如,如果我在对象上有多对多关系)

这是代码:

在减速机

case "RECEIVE_DATA":
      return {
        ...state,
        byId: [...state.byId, action.payload.data]
      };

新动作:

export function action() {
  return {
    type: RECEIVE_DATA,
    payload: {
      data: {
        id: Math.floor(Math.random() * 2),
        value: Math.floor(Math.random() * 10000)
      }
    }
  };
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM