1

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

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

所以我认为我需要从表单(react-final-form)中持久化数据,如果成功响应包含 memberId(来自后端),使用这些数据更新当前的 Redux 存储实体(成员配置文件)。

我正在考虑将更新请求数据保存到存储实体减速器中-> 使用像 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 中间件中)将临时数据保存到存储中(可能通过另一个动作)以通过这种方法达到我需要的内容?

4

1 回答 1

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;

不要忘记在你的配置中注册你的减速器!希望能帮助到你!

于 2018-09-26T13:15:18.280 回答