将异步操作分派给redux-saga后如何在redux存储中捕获更改

时间:2020-06-28 12:00:34

标签: reactjs redux redux-saga

在我的登录组件中,我尝试单击按钮登录,然后调用相应的函数“ handleLogin”。在此函数中,我调度了一个异步函数,其中包含我的用户凭据作为有效负载。在我的传奇中,我正在发出一个请求,如果响应得到了这样的字段,则会放置一个错误来存储,否则我在那里设置了一个用户。默认情况下,存储区中的错误字段为“ false”。在我分派动作的组件中,我想在成功/不成功响应之后立即知道存储中错误字段的状态。当我尝试使用错误的凭据登录并将错误状态记录到控制台中时,我首先会获得错误的“旧”(初始)值:false,而不是错误:true。仅在第二次尝试登录后,错误才会设置为true。分派异步操作后,有没有办法知道存储中错误的实际状态?

减速器:

const initialState = {
  userData: [],
  error: false
};

const userReducer = (state = initialState, action) => {
  switch (action.type) {
  case SET_USER:
    return {
      ...state,
      userData: action.payload
    }
  case SET_ERROR:
    return {
      ...state,
      error: action.payload
    }
  default:
    return state;
  }
};

SAGAS:

function* handleUserLoad(payload) {
  try {
    const user = yield call(
      loginUser,
      payload
    );
    if(user.data.errors) {
      yield put(setError(true))
    } else {
      yield put(setError(false))
      yield put(setUser(user.data.data.loginUser));
    }
  } catch (error) {
    console.log(error);
  }
}

export default function* userSaga() {
  while (1) {
    const {payload} = yield take(GET_USER);
    yield call(handleUserLoad,payload);
  }
}

登录组件部分:

const handleLogin = async() => {
    setShouldValidate(true);
    if (allFieldsSet) {
      try {
        loginUser(user)
        // LOGIN ERROR HERE DISPLAYS THE PREVIOUS STATE 'false'
        // INSTEAD OF ACTUAL TRUE AFTER loginUser
        // IF I LOG WITH WRONG CREDENTIALS
        console.log(loginError);
      } catch (e) {
        console.error(e);
      }
    }
  };

2 个答案:

答案 0 :(得分:1)

组件中的

loginUser(user)是一个异步函数,因此不能期望console.log(loginError);在下一行中正确记录loginError的值。

解决方案:

第一: 您可以在redux中将登录组件绑定到错误状态。 Saga根据成功/失败的响应修改状态后,您的登录组件将重新呈现。因此,在渲染中,如果您将console.log,那么您可能会看到loginError的值正确显示。因此,仅在渲染中,您可以根据要显示的“ loginError”将所需组件放置在其中。

第二: 您可以跳过Saga,直接在当前位置的登录组件中等待登录API响应(使用fetch / axios从此处调用API)。在这种情况下,您可以在await调用完成后立即获得正确的登录响应,然后继续执行代码

答案 1 :(得分:0)

我对存储中error的默认值做了些微更改。现在它是'null'而不是false。因此,我可以检查useEffect中是否将其设置为false / true并执行其他逻辑。