React + Redux PUT API请求来编辑我的Redux存储中的数据

时间:2018-09-26 12:27:53

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

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

PUT请求后,我的后端api仅返回状态码和原因(如果错误)或memberId(如果成功)。我无法更改后端端点,以返回新的成员概要文件对象,因为我们的Web服务器之外还有另一台“全局”服务器,其工作原理与该服务器相同,我无法更改。

因此,我认为我将需要持久保存来自Form(react-final-form)的数据,并且如果成功响应包含memberId(来自后端),请使用此数据来更新当前的Redux存储实体(成员配置文件)。 / p>

我正在考虑使用诸如UPDATING_MEMBER_PROFILE之类的键将更新请求数据保存到实体实体reducer->中,并且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中间件中)将临时数据保存到存储中(可能通过其他操作),以达到此方法所需的条件?

1 个答案:

答案 0 :(得分:0)

您在正确的道路上。尝试分派一个操作以将请求发送到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.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;

别忘了在您的配置中注册减速器! 希望对您有帮助!