如何在将异步操作分派到 redux-saga 后捕获 redux 存储中的更改
How to catch changes in redux store after dispatching async action to redux-saga
在我的登录组件中,我尝试在单击按钮时登录,然后调用相应的函数 'handleLogin'。在此函数中,我使用我的用户凭据作为有效负载分派一个异步函数。在我的传奇中,如果响应有这样的字段,我正在发出一个请求,将错误存储起来,否则我会在其中设置一个用户。默认情况下,存储中的错误字段是 'false'。在我发送动作的组件中,我想知道 successfull/unsuccessful 响应后存储中错误字段的状态。当我尝试使用错误的凭据登录并将错误状态记录到控制台时,我首先得到错误的 'old'(初始)值: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;
}
};
传奇:
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);
}
}
};
loginUser(user)
在你的组件中是一个异步函数,所以你不能期望 console.log(loginError);
在下一行正确记录 loginError 的值。
解法:
第一个:
您可以将登录组件绑定到 redux 中的错误状态。一旦 Saga 根据 successful/unsuccesful 响应修改了状态,您的登录组件将重新呈现。因此,在渲染中,如果您 console.log 那么您可能会看到 loginError
的值正确出现。因此,在仅渲染中,您可以根据要显示的“loginError”放置您想要的组件。
第二个:
您可以跳过使用 Saga 并直接在当前位置的登录组件中等待您的登录 API 响应(使用 fetch/axios 从此处本身调用 API )。在这种情况下,您将能够在 await 调用完成后立即获得正确的登录响应,然后您可以继续执行您的代码
我对商店中错误的默认值进行了细微的更改。现在它是 'null' 而不是 false。因此我可以检查它是否在 useEffect 中设置为 false/true 并执行其他逻辑。
在我的登录组件中,我尝试在单击按钮时登录,然后调用相应的函数 'handleLogin'。在此函数中,我使用我的用户凭据作为有效负载分派一个异步函数。在我的传奇中,如果响应有这样的字段,我正在发出一个请求,将错误存储起来,否则我会在其中设置一个用户。默认情况下,存储中的错误字段是 'false'。在我发送动作的组件中,我想知道 successfull/unsuccessful 响应后存储中错误字段的状态。当我尝试使用错误的凭据登录并将错误状态记录到控制台时,我首先得到错误的 'old'(初始)值: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;
}
};
传奇:
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);
}
}
};
loginUser(user)
在你的组件中是一个异步函数,所以你不能期望 console.log(loginError);
在下一行正确记录 loginError 的值。
解法:
第一个:
您可以将登录组件绑定到 redux 中的错误状态。一旦 Saga 根据 successful/unsuccesful 响应修改了状态,您的登录组件将重新呈现。因此,在渲染中,如果您 console.log 那么您可能会看到 loginError
的值正确出现。因此,在仅渲染中,您可以根据要显示的“loginError”放置您想要的组件。
第二个: 您可以跳过使用 Saga 并直接在当前位置的登录组件中等待您的登录 API 响应(使用 fetch/axios 从此处本身调用 API )。在这种情况下,您将能够在 await 调用完成后立即获得正确的登录响应,然后您可以继续执行您的代码
我对商店中错误的默认值进行了细微的更改。现在它是 'null' 而不是 false。因此我可以检查它是否在 useEffect 中设置为 false/true 并执行其他逻辑。