首页 > 解决方案 > 将 Promise.all 与 React-Redux-Thunk 一起使用的更好/正确方法是什么?

问题描述

export const FETCH_DB_BEGIN = 'FETCH_DB_BEGIN'
export const FETCH_DB_SUCCESS = 'FETCH_DB_SUCCESS'
export const FETCH_DB_FAILURE = 'FETCH_DB_FAILURE'

export const fetchDatabase = () => {
    return dispatch => {
        const profile_url = 'localhost:5000/profiles'
        const release_url = 'localhost:5000/releases'
        const emp_url = 'localhost:5000/users'
        let promises = []

        let options = {
            headers: header,
            method: 'get',
            mode: 'cors',
            body: null,
        }
        dispatch(fetchDbBegin());

        // run the script async. change state when it's done.
        let profile_promise = new Promise((resolve, reject) => {
            fetch(profile_url, options)
                .then(res => res.json())
                .then(resText => {
                    // Use Dispatch Here?
                })
        }).catch(err => {
            console.log(err)
        })
        promises.push(profile_promise)

        // run the script async. change state when it's done.
        let release_promise = new Promise((resolve, reject) => {
            fetch(release_url, options)
                .then(res => res.json())
                .then(resText => {
                })
        }).catch(err => {
            console.log(err)
        })
        promises.push(release_promise)

        // run the script async. change state when it's done.
        let emp_promise = new Promise((resolve, reject) => {
            fetch(emp_url, options)
                .then(res => res.json())
                .then(resText => {

                })
        }).catch(err => {
            console.log(err)
        })
        promises.push(emp_promise)

        Promise.all(promises).then(values => {
            console.log(values)
        })
    }
}

export const fetchDbBegin = () => ({
    type: FETCH_DB_BEGIN
});

export const fetchDbSuccess = (data) => ({
    type: FETCH_DB_SUCCESS,
    payload: { data }
});

export const fetchDbFailure = (err) => ({
    type: FETCH_DB_FAILURE,
    payload: { err }
});

我正在重构一个 React 类组件以使用Redux. 它最初在内部有所有 API 调用,componentDidMount而且非常混乱。

我正在使用redux-thunk将其从类组件中移出。

fetchDatabasein my完成了在类组件中所做的databaseAction.js一切。componentDidMount

通常,如果它是单个 API 调用,我会fetchDbSuccess在 API 调用成功完成时分派它。但是,使用Promise.Allwhich 需要三个异步 API 调用,我不确定是否应该

  1. fetchProfileSuccess为每个 API 调用( 、fetchReleaseSuccess和)创建一个单独的操作,并在每个 Promise 的末尾(我在代码fetchUserSuccess中放入的地方)分派它们中的每一个。//Use Dispatch Here?

或者

  1. fetchDbSuccessPromise.all问题得到解决时,只需发送单人。

如果我选择做 2,我应该更新states我的减速器中的所有三个吗?

谢谢

标签: javascriptreactjsreduxredux-thunk

解决方案


如果你有关心状态更新的代码,你应该只调度和更新状态。例如,如果您只想显示一个微调器,然后在完全完成后让微调器消失,您的用户不一定关心每个原子操作,因此您不需要将其反映在状态中。如果您有一个确实显示每个的 UI,那么您会想要那些额外的调度。

顺便说一句,你的 Promises 看起来有点过于复杂。如果您决定不需要这些额外的状态更改,则可以简化为:

export const FETCH_DB_BEGIN = 'FETCH_DB_BEGIN'
export const FETCH_DB_SUCCESS = 'FETCH_DB_SUCCESS'
export const FETCH_DB_FAILURE = 'FETCH_DB_FAILURE'

export const fetchDatabase = () => {
    return dispatch => {
        dispatch(fetchDbBegin());

        const urls = [
            'http://localhost:5000/profiles',
            'http://localhost:5000/releases',
            'http://localhost:5000/users'
        ];

        const options = {
            headers: header,
            method: 'get',
            mode: 'cors',
            body: null,
        }

        const fetchJson = url => fetch(url, options).then(res => res.json());

        Promise.all(urls.map(fetchJson))
            .then(([profile, release, employee]) => {
                dispatch(fetchDbSuccess({ profile, release, employee }));
            })
            .catch(err => {
                dispatch(fetchDbFailure(err));
            });
    }
}

export const fetchDbBegin = () => ({
    type: FETCH_DB_BEGIN
});

export const fetchDbSuccess = (data) => ({
    type: FETCH_DB_SUCCESS,
    payload: { data }
});

export const fetchDbFailure = (err) => ({
    type: FETCH_DB_FAILURE,
    payload: { err }
});

推荐阅读