问题:
Let's say I have a saga that looks so:
export function* incrementAsync(action) {
try {
const res = yield call(Api.signin.create, action.payload);
yield put({...
可以将文章内容翻译成中文,广告屏蔽插件会导致该功能失效:
问题:
Let's say I have a saga that looks so:
export function* incrementAsync(action) {
try {
const res = yield call(Api.signin.create, action.payload);
yield put({
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
};
} catch (e) {
yield put({ type: USER_SIGN_IN_FETCH_ERROR_NETWORK });
}
}
The fech was a success, but that doesn't mean that the user was actually logged in:
res.data.auth.error
could be true
My question is whether I should do things like:
if (//user was succesfully logged in)
yield put(//user was successfully logged in)
else if //wrong username
yield put(//wrong username)
else if //wrong password
yield put(//wrong password)
Or should I have only one for success and one for error, and in the reducer analyze the logic and build the store relative to the response data?
回答1:
Error logic should always be handled at sagas
. In this particular case your API is not throwing a correct error because if your API call was not a success
(200
, for example), that logic should be handled at your catch statement.
Why is this error not being handled there? If you are using axios
, this could happen as a consequence of a bad design of the API (i.e. returning 200 instead of 400 for an error in signin in). If it's just you doing it by hand you should throw an error and handle that logic at catch
in sagas
.
So my recommendation is:
- Throw an error to the sagas to handle error logic at
catch
statement.
If you have to parse the response in order to programmatically throw the error do it at the API layer if you can.
Make a specific action to handle the signup error OR just make a generic FAIL action and pass an error message to it(an then store it at redux to show it).
It should look something like:
export function* incrementAsync(action) {
try {
const res = yield call(Api.signin.create, action.payload);
yield put({
type: USER_SIGN_IN_FETCH_SUCCESS,
payload: res.data.auth
};
} catch (error) {
yield put({ type: USER_SIGN_IN_FAIL, payload: error.message });
}
}
回答2:
I'd always move as much logic as possible to the reducer. Logic there is more visible in the dev tools, if you do it in the saga it can be harder. It is also easier to test, as it's a synchronous and pure function. Also, USER_SIGN_IN_FETCH_SUCCESS
seems perfectly meaningful to me for an action send from saga to reducer (actions from components to reducer should be less technical).