Redux Saga:登录按钮的加载指示器

时间:2018-12-21 11:35:49

标签: redux-saga saga

我们使用以下传奇故事通过电话注册用户:

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”

1 个答案:

答案 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会带来更多麻烦,而不是其价值。