【问题标题】:React useReducer find and change single object in stateReact useReducer 查找和更改状态中的单个对象
【发布时间】:2020-04-04 16:34:09
【问题描述】:

我有一个状态对象,其中包含名称rows 内的数组。该数组包含一个对象列表:

{_id: "5e88ad4c5f6f7388d50b9480",
stampa: "Confezione",
S: 0,
M: 0,
L: 0,
XL: 0,
coloured: "",
modello: "",
SKU: ""}

现在,我在一个表单中调度了一个动作,其中有效负载包含完全相同的对象,唯一的区别是可以更改的键 SMLXL

然后,在我的 reducer 中,我想通过匹配 _id 来找到原始状态下的相同对象,然后使用有效负载附带的对象对其进行更新。 这是我的尝试,但是我收到以下错误:

TypeError: state.rows.map is not a function

case "UPDATE_ROW":
      return state.rows.map((row) =>
        row._id === action.payload._id
          ? {
              ...row,
              _id: action.payload,
            }
          : row
      );

我怎样才能更好地解决这个问题?

编辑: 这是我的减速机:

export default (state, action) => {
  switch (action.type) {
    case "UPDATE_STATE":
      return {
        ...state,
        rows: action.payload,
      };
    case "SET_ERROR":
      return {
        ...state,
        error: action.payload,
      };
    case "UPDATE_ROW":
      console.log("updating", action.payload);
      return state.rows.map((row) =>
        row._id === action.payload._id
          ? {
              ...row,
              _id: action.payload,
            }
          : row
      );

    default:
      return state;
  }
};

这是我的状态:

import React, { createContext, useReducer } from "react";
import AppReducer from "./AppReducer";

// Initial State
const initialState = {
  rows: [],
};

export const GlobalContext = createContext(initialState);

// Provider component
export const GlobalProvider = ({ children }) => {
  const [state, dispatch] = useReducer(AppReducer, initialState);
  console.log(state);

  return (
    <GlobalContext.Provider value={[state, dispatch]}>
      {children}
    </GlobalContext.Provider>
  );
};

【问题讨论】:

  • 发布您的整个useReducer 代码。
  • 确保state.rows是一个数组

标签: javascript reactjs ecmascript-6 react-hooks


【解决方案1】:

您遇到的主要问题是您应该默认 state.rows 是一个数组,以便停止类型错误。 除此之外,据我所见,您的逻辑似乎很好。

编辑:

好的,您的问题似乎是您在运行“UPDATE_ROW”案例时没有返回完整状态。如果你使用它,我相信这个问题应该得到解决。

我还修复了 reducer 案例中的逻辑。看起来您在 _id 属性中添加了整个有效负载对象,同时保持该行的其余部分相同。而不是使用有效负载属性更新行。

export default (state, action) => {
  switch (action.type) {
    case "UPDATE_STATE":
      return {
        ...state,
        rows: action.payload,
      };
    case "SET_ERROR":
      return {
        ...state,
        error: action.payload,
      };
    case "UPDATE_ROW":
      console.log("updating", action.payload);
      return {...state, rows:state.rows.map((row) =>
        row._id === action.payload._id
          ? {
              ...action.payload
            }
          : row
      )};

    default:
      return state;
  }
};

【讨论】:

  • 我已根据您的代码进行了更新。我相信这现在应该会有所帮助。
  • 谢谢,那是错误!我没有返回状态!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-01
  • 2021-03-02
  • 1970-01-01
  • 2022-01-05
  • 2018-09-08
  • 2020-03-21
  • 2023-01-09
相关资源
最近更新 更多