【问题标题】:adding new item to the nested data structure in reducer state在 reducer 状态下向嵌套数据结构中添加新项
【发布时间】:2020-06-29 16:33:48
【问题描述】:

我一直试图在不使用任何实用程序库的情况下使用纯 JS 将新项目添加到我的初始状态,这似乎非常复杂。 这里是我初始状态的结构:

  const initialState = {
  isLoading: false,
  events: [
    {
      year: 2021,
      place: [
          { id: 1, name: "BD" }, 
          { id: 1, name: "BD Test" }
       ]
    },
    { year: 2020, 
     place: [
         { id: 2, name: "AMS" },
        { id: 1, name: "AMS TEST" }
      ] 
    }
  ]
};

我想为匹配的项目添加一个新属性,这样状态就会像这样修改:

    const initialState = {
     isLoading: false,
     events: [
    {
      year: 2021,
      place: [{ id: 1, name: "BD", newProp:"NewValue" }, 
             { id: 1, name: "BD Test" }
       ]
    },
    { year: 2020, 
     place: [
            { id: 2, name: "AMS" },
            { id: 1, name: "AMS TEST" }
   ] }
  ]

}; 在我的减速机中,我尝试过:

 case actionType.TOGGLE_INFO:
  return {
    ...state,
    events: state.events.map((x) => x.place[0].id === action.id
      ? { ...x, place: [{ ...x.place[0], newProp: "new Value"}] }
      : x),
  };

该代码更新状态中的值,但随后仅显示事件中的一项(地点)。有什么办法,我仍然可以显示所有事件并在事件中更新选定的位置(通过添加新属性)。我一直在尝试修复它一段时间。因此,我们将不胜感激任何帮助。提前致谢。 到目前为止我的减速器:

   const initialState = {
     isLoading: false,
     events: [
        {
         year: 2021,
         place: [{ id: 1, name: "BD" }, { id: 1, name: "BD Test" }]
       },
       { year: 2020, 
         place: [{ id: 2, name: "AMS" }, { id: 1, name: "AMS TEST" }] }
  ]
};
const commonReducer = (state = initialState, action = {}) => {
  switch (action.type) {
    case "FETCH_EVENTS":
      return {
        ...state
      };
    case "TOGGLE_INFO":
      console.log(state.events);
      return {
        ...state,
        events: state.events[0].map(event =>
          event.id === action.id
            ? { ...event, place: [{ ...event.place[0], isTouched: true }] }
            : event
        )
      };
    default:
      return state;
  }
};
export default commonReducer;

【问题讨论】:

    标签: javascript arrays reactjs object react-redux


    【解决方案1】:

    我很难理解您想要实现的目标,但无论如何我都会尽力帮助您。

    如果你能过完这一年也会更容易,因为你的数据是结构化的,但我们假设你不能:

        return {
        ...state,
        events: state.events.map(event => {
            if(event.place.find(x => x.id === action.id)) {
                return {
                    ...event,
                    place: [...event.place, {newProp: "newValue"}]
                }
            } else {
                return event
            }
        })
    }
    

    我希望这会有所帮助,但如果没有,我希望您向我展示您尝试实现的目标之前和之后。

    更新:

    初始状态(你有重复的键,所以我改变了它):

    const initialState = {
    isLoading: false,
    events: [
        {
            year: 2021,
            place: [{ id: 1, name: "BD" }, { id: 2, name: "BD Test" }]
        },
        { year: 2020, place: [{ id: 3, name: "AMS" }, { id: 4, name: "AMS TEST" }] }
    ]
    };
    

    减速器:

    const commonReducer = (state = initialState, action = {}) => {
    switch (action.type) {
        case "UpdateEvents":
            return {
                ...state
            };
        case "UpdatePlace":
            console.log(state.events);
            return {
                ...state,
                events: state.events.map(event => {
                    const place = event.place.find(x => x.id === action.id);
                    if (place) {
                        return {
                            ...event,
                            place: event.place.map(x => {
                                if (x.id === action.id) {
                                    return { ...x, isTouched: true };
                                } else {
                                    return x;
                                }
                            })
                        };
                    } else {
                        return event;
                    }
                })
            };
        default:
            return state;
    }
    };
      export default commonReducer;
    

    Place.js:

    return (
        <div>
        ID: { props.place.id }
        Name: { props.place.name }
        <div>{ props.place.isTouched ? "TOUCHED" : "" } < /div>
        < button onClick = { setTouched } > SetTouched < /button>
        < /div>
      );
     };
    

    https://codesandbox.io/s/wonderful-black-m6il1

    【讨论】:

    • 嘿,谢谢您的回复。我试图在调度“TOGGLE_INFO”操作时向“place”添加一个新属性。因此,在我的组件中,我有一个父组件,它首先显示事件,然后在子组件中,我从事件数组中呈现相应的位置。所以,在我渲染地点的子组件中,我想启动一些点击处理程序,将新项目添加到所选地点。希望解释能帮助你理解。恐怕您给出的代码可能不起作用
    • 所以据我了解,您在更新状态时遇到了问题?如果是这样,你能给我一个之前状态的例子,一个你要调度的动作的例子和之后的期望状态吗?只需将其添加到您的问题中
    • 是的,我在更新状态时遇到问题,我在问题中添加了减速器。它的格式为initialState(更新状态之前)
    • codesandbox.io/s/holy-tdd-v3gbd?file=/src/reducers/…,沙盒也可以帮助你理解,
    猜你喜欢
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    相关资源
    最近更新 更多