使用回调从redux saga进行组件状态更新的正确方法

时间:2019-07-06 04:42:48

标签: reactjs react-redux redux-saga

如何根据API响应更好地更新视图。假设我们有一个设置,成功登录后应将用户重定向到仪表板视图,并在登录屏幕上显示任何错误的警报消息。

我目前使用的是

我经常打电话给动作创建者,最后敲打端点以进行响应。然后根据该响应调度相关的成功或失败action,以更新我使用connect(mapStateToProps, mapActionsToProps)在组件中订阅的全局状态。

问题

假设我的全局状态为loginSuccess,并且在我的Login组件中将其用于重定向或错误处理。例如,我还想处理“密码重设”屏幕的响应。因此,我在全局状态下存储了另一个信息,并在相关组件中使用了它。

这是不是一个问题?

我觉得在全球状态下存储的信息太多了。

我阅读了哪些新内容?

因此,我开始阅读有关将callback传递给处理响应的操作创建者的信息。这样,错误处理逻辑就保持在组件本地。

示例

Login.js

componentDidMount(){
 this.props.login({
        data, // login payload.
        callback: (response) => this.handleResponse(response)
 })
}

// response handler.
handleResponse = response => {
   this.setState({isError: response.isError});
}

render () {
   /* Use the this.state.isError to determine either to redirect or show error */
}

Actions.js

export const login = payload => ({
  type: ATTEMPT_LOGIN,
  payload
})

saga.js

// login handler in saga.
function* loginAttempt({payload}) {
  const {data, callback} = payload;
  try {
     const resp = yield apiCaller.call(method, url, data, headers); // utitly to fetch data and return a standard response.
     callback(resp);
  }catch(error){
     callback(DEFAULT_ERROR_RESPONSE); // {isError: true, message: 'Something went wrong'}
  }
}

哪个更好?

有没有更好的方法来处理这种事情?你们如何处理?

1 个答案:

答案 0 :(得分:1)

您所说的“全局”状态是Redux做出的拥有单个存储的设计决策。可以向存储中添加任意数量的loginSuccess属性。为了使它们井井有条,您可以使用combineReducers将您的商店分成多个部分。

您已经在使用Redux和Redux Saga。您不必为诸如此类的问题使用回调。让reducer,sagas和selector照顾流程:

function* loginAttempt(payload) {
  try {    
    const response = yield apiCaller.call(method, url, data, headers);
    yield put(LOGIN_SUCCESS, response);
  }catch(error){
    yield put(LOGIN_ERROR, error);
  }
}

默认状态可以是:

user: null,
loginRequestStatus: {
  inProgress: false,
  error: false,
}

ATTEMPT_LOGIN的减速器应设置为进行中。 LOGIN_SUCCESS的减速器应设置用户。 LOGIN_ERROR设置错误。使选择器可以使用selectAuthUserselectIsLoginInProgress之类的选择器。如果您使用的路由器可以与Redux通信,例如router5,甚至可以从Saga重定向。