首页 文章

在Redux-saga中,如何在一个saga的fetch中调用一个传奇?

提问于
浏览
0

在我的React应用程序中,有一个Saga调用后端API来检索一些图表数据 . 请阅读源代码

function fetchData () {
    return fetch(`${config.base}dashboard_charts.json`)
    .then((response) => {

        if (response.status === 200) {
            return response.json();
        } else if (response.status === 403) {
             return 'logon';
        }
    });
}

function * getData (action) {
    try {
        const charts = yield call(fetchData);

        if (charts === 'logon') {
            yield logon();
        } else {
            yield put({ type: UPDATE_DASHBOARD_CHART, charts });
        }
    } catch (error) {
        yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
    }
}

function * logon (action) {
    yield auth();
}

export default function * portfolio () {
    yield [
        takeEvery(FETCH_DASHBOARD_CHART, getData)
    ];
};

在fetchData函数中检查http响应状态,如果状态为200,则直接返回响应 . 但是如果服务器端返回403,则意味着客户端需要进行身份验证,因此程序将转到auth()并执行登录 .

但是,http响应状态代码检查在某种程度上是应用于所有API调用的一般功能 . 所以我不想在每个传奇中重复这种代码 . 为此,我写了一个服务'responseHandler'来对里面的响应代码进行分组,如下所示:

export default function responseHandler (resp) {
    if (resp.status === 401 || resp.status === 403) {
        yield auth();
    } else if (resp.status === 200) {

    } else {
        console.log('error handling');
    }
};

它将在fetchData内部调用

return fetch(`${config.base}dashboard_charts.json`)
    .then((response) => {
        responseHandler(response);
    });

但这种方法永远不会奏效 . 'yield auth()'在responseHandler中无效 .

任何人都可以建议如何更好地设计此案例的代码?

1 回答

  • 2

    也许组织逻辑有几个意义?

    首先,可以修改fetch-wrapper,以便在响应代码的HTTP的起源不满足形成成功结果的期望的情况下,执行到catch-section的转换 . 它将允许以纯Promise的形式保存 fetchData 函数,而无需将生成器逻辑输入其中 .

    其次, authlogon 函数的本质并不是特别清楚 . 如果通过此类操作的结果生成登录表单,则通过适当的redux操作实现它 . 如果需要转换到其他页面,请使用 react-redux-router .

    function fetchData () {
            return fetch(`${config.base}dashboard_charts.json`).then(response => (
                (response.status === 200) ? response.json() : Promise.reject('logon')
            ));
        }
    
    function* getData (action) {
        try {
            const charts = yield call(fetchData);
            yield put({ type: UPDATE_DASHBOARD_CHART, charts });
        } catch (error) {
            yield put({ type: UPDATE_DASHBOARD_CHART, charts: [] });
            if(error.message === 'logon') {
                yield put({ type: PERMORM_AUTORIZE });
            }
        }
    }
    
    export default function * portfolio () {
        yield [ takeEvery(FETCH_DASHBOARD_CHART, getData) ];
    };
    

    你的逻辑是否更复杂,只需使用 redux-saga 来自 redux-saga . 它允许执行更复杂的任务 .

相关问题