【问题标题】:React + Redux PUT api request to edit data in my redux storeReact + Redux PUT api 请求编辑我的 redux 存储中的数据
【发布时间】:2018-09-26 12:27:53
【问题描述】:

我的应用程序使用 redux 将来自后端 API 的数据保存在 redux 存储实体 reducer 中,例如 MEMBER 数据对象,它在 App 中的多个组件之间共享以显示成员详细信息。现在我正在实现 EditProfile 组件,它应该从表单中获取数据,将其作为 PUT 请求发送到后端 API,如果请求成功结束 (到此为止) 更新 redux 商店中的当前会员资料实体。我试图找到类似“最佳实践”的东西来达到这个 redux 商店更新。我已经实现了基本的 api 中间件(类似于 Redux 实际应用程序示例中的一个),但我不完全确定,如何通过状态更新到达部分。

我的后端 api 在 PUT 请求后仅返回状态代码和原因(如果错误)或 memberId(如果成功)。我无法更改后端端点以返回新的成员配置文件对象,因为我们的网络服务器之外还有另一个“全局”服务器,它与这个服务器相同,我无法更改它。

所以我认为我需要保存来自 Form (react-final-form) 的数据,如果成功响应包含 memberId (来自后端),请使用此数据更新当前的 Redux 存储实体 (Member Profile)。

我正在考虑 将更新请求数据保存到商店实体减速器 -> 使用像 UPDATING_MEMBER_PROFILE 这样的键和 id 请求以成功结束,将这两个对象合并为一个并清除 UPDATING_ 部分。请问大家有什么建议吗?

更新:

要在我的代码中调用 API,我有如下操作:

memberAction.js

export const updateProfile = values => ({
type: API,
  payload: {
    url: "/members/update",
    method: "PUT",
    data: values,
    meta: {
      label: MEMBER_PROFILE,
      success: [], // action callbacks onSuccess
      error: [] // action callbacks onError
    }
  }
});

然后我的 API 中间件负责 action.type === API 并为 API_REQUEST、API_SUCCESS 和 API_ERROR 类型生成操作,其中包含来自第一个 fetchProfile 操作的实体和标签。它看起来像:

apiMiddleware.js

...getting Info from origin action about request here

next(action);
dispatch(apiRequest(entity, label));

return callApi(url, method, data)
  .then(response => {
    dispatch(apiSuccess(response.status, response, label));
    dispatch(success(response)); // Dispatch callbacks...
  })
  .catch(error => {
    dispatch(apiError(response.status, error, label));
    dispatch(error(response)); // Dispatch callbacks...
  });

在中间件服务器和调度另一个动作之后,我的 api reducer 将分配来自 API 的数据以按实体存储,例如:

apiReducer.js

const apiEntitiesReducer = (state = {}, action) => {
  switch (action.type) {
    case API_REQUEST: 
      return {
        ...state,
        [action.payload.label]: {
          error: false,
          data: null
        }
      };
    case API_ERROR:
    case API_SUCCESS:
      return {
        ...state,
        [action.payload.label]: {
          error: action.isError,
          data: action.payload.data
        }
      };
    default:
      return state;
  }
};

这些只是为了简单起见的伪代码(我暂时不使用 thunk...)。所以我需要在某个地方(可能在 api 中间件中)将临时数据保存到存储中(可能通过其他操作)以通过这种方法达到我需要的内容?

【问题讨论】:

    标签: reactjs react-native redux react-redux react-final-form


    【解决方案1】:

    你走在正确的道路上。尝试分派一个操作以将请求发送到 API,然后(成功后)分派另一个操作来更新您的商店。类似的东西

    profile.js

    export const updateProfile = newMemberProfile => { //your action, using thunk here
      return dispatch => {
       fetch(UPDATE_URL, {
            method: "PUT",
            body: JSON.stringify(newMemberProfile),            
        })
        .catch(err => {
          console.log(err);
          alert("Profile update failed, please try again!");
        })
        .then(res => {
            dispatch(memberProfileUpdated(newMemberProfile));
        });
       }
    }
    
    export const memberProfileUpdated = newMemberProfile => {
      return {
        type: UPDATING_MEMBER_PROFILE,
        newMemberProfile
      };
    };
    

    然后为这个常量添加一个reducer(为了清楚起见,将所有常量和reducer放在单独的文件中) reducer.js

    const initialState = {
        memberProfile: null,
    };
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case UPDATING_MEMBER_PROFILE:
          return {
            ...state,
            memberProfile: action.newMemberProfile
          };
        default:
          return state;
      }
    };
    
    export default reducer;
    

    别忘了在你的配置中注册你的 reducer! 希望对您有所帮助!

    【讨论】:

    • 你好尼古拉!非常感谢您的回答。对于我正在使用的方法,我无法将其概括得足够多,这很好,因为我没有写任何关于我的方法的内容。我已经用我的方法的一些代码示例更新了我的原始问题。我可以请你看一下吗?非常感谢!
    • 有点乱,但据我所知,action.payload.data 是您的新个人资料。只需发送另一个操作来更新配置文件(如我的示例中所示),并使用另一个减速器设置新配置文件。并且:dispatch(apiSuccess(response.status, response, label)); -> 也许您必须用 data 替换第二个参数,因为在成功的情况下您不需要服务器的响应,但是您必须将新的配置文件传递给减速器,以更新您的商店。跨度>
    • 非常感谢 :) 我会尝试使用它,只要它能够正常工作。
    • 我有同样的问题,但状态部分是一个数组。如何处理?我试过 filter() 但它不起作用。
    • yaksh 你到底想做什么?
    猜你喜欢
    • 2019-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 2018-02-26
    • 2021-06-18
    • 2018-09-24
    • 1970-01-01
    相关资源
    最近更新 更多