我们使用以下传奇故事通过电话注册用户:
function* signup() {
while (true) {
const {phone} = yield take("APP_SIGNUP");
nav.toCode();
const responseSignup = yield call(fetch.signUp, phone);
if (!responseSignup.success) {
yield put({type: "SIGNUP_SERVER_ERROR"});
continue;
}
let i;
for (i = 0; i < 3; i++) {
const {code} = yield take("APP_CHECK_CODE");
// MARKED LINE
const {success} = yield call(fetch.checkCode, {
phone,
code,
});
if (success) break;
yield put({ type: "APP_CHECK_CODE_WRONG" });
}
// code ok
if (i < 3) {
nav.toTabs();
yield put({ type: "APP_CHECK_USER" });
}
...
用户输入他的电话号码,并显示一个屏幕,其中他填写4位数的代码-您知道演习。
我们要添加一个加载指示器。是否有办法将承诺退还给称为APP_CHECK_CODE操作*的任何人?
*在代码中标记为“ MARKED LINE”
答案 0 :(得分:2)
您可以从一个笨拙的人那里返回一个承诺,但是如果您要坚持使用sagas,除了更改redux存储状态之外,没有一种简单的方法可以让发出动作的组件知道传奇已经完成。
所以我要解决的方法是使用减速器,例如:
export (state = {checkingCode: false}, action) => {
switch (action.type) {
case APP_CHECK_CODE:
return {...state, checkingCode: true};
case APP_CHECK_CODE_WRONG:
case APP_CHECK_CODE_SUCCESS:
return {...state, checkingCode: false};
default:
return state;
}
}
然后根据checkingCode
值显示/隐藏加载指示器。
从理论上讲,如果您确实想将状态保留在组件本身中,则可以将类似观察者的内容传递给传奇,然后等待。
// component
const observable = Observable.create(observer => {
this.setState({loading: true});
dispatch({type: APP_CHECK_CODE, observer});
});
observable.subscribe({
complete: () => this.setState({loading: false}),
});
// saga
const {code, observer} = yield take("APP_CHECK_CODE")
...
observer.complete();
但是,老实说,这感觉很神奇,而且imo会带来更多麻烦,而不是其价值。