我该如何在React容器组件中进行API调用?

时间:2018-07-16 09:01:31

标签: javascript reactjs

目前,我有一个React Redux应用程序,其中存储了商店中的全部状态项。我设置了一些操作,以从后端API填充状态。我使用容器和表示性组件,并在容器中使用mapDispatchToProps为其子级获取所需的所有状态,然后使用mapStateToProps将状态作为道具传递。

目前,这是我在容器组件中进行这些初始API调用的方式:

componentDidMount() {
    this.props.getResources()
        .then(() => {
            this.props.getUsers()
                .then(() => {
                    this.props.getComments()
                        .then(() => {
                            this.props.getFiles()
                                .then(() => {
                                    this.props.getAlts()
                                        .then(() => {
                                            this.props.getSubjects()
                                                .then(() => {
                                                    this.props.getTemplates()
                                                        .then(() => {
                                                            this.props.getResourceTags()
                                                                .then(() => {
                                                                    this.setState({
                                                                        resourcesLoaded: true
                                                                    });
                                                                });
                                                        });
                                                });
                                        });
                                });
                        });
                });
        });
}

这似乎很荒谬。有没有更清洁的方法来发出这些API请求或重构我的动作,以便将它们压缩为一个动作?

2 个答案:

答案 0 :(得分:4)

使用Promise.all

同时运行所有功能/承诺的最有效方式
componentDidMount() {
    Promise.all([
        this.props.getResources(),
        this.props.getComments(),
        this.props.getFiles(),
        this.props.getAlts(),
        this.props.getSubjects(),
        this.props.getTemplates(),
        this.props.getResourceTags()
    ]).then(() =>
        this.setState({ resourcesLoaded: true })
    )
}

Promise.all相比,使用await的好处是await依次运行每个功能/承诺,而Promise.all同时运行所有功能。

详细说明

所以当我们使用

await getResources()
await getComments()
...
...

await关键字将等待getResources()完成,然后将运行getComments()并等待其完成,此操作将继续。

使用Promise.all时,它将立即运行所有功能,并且将等到每个功能都执行后才运行.then(...)部分。

答案 1 :(得分:3)

您可以使用async - await代替回调模式。这是ES6的功能。

示例:

async componentDidMount() {
    try {
        await this.props.getResources()
        await this.props.getComments()
        await this.props.getFiles()
        await this.props.getAlts()
        await this.props.getSubjects()
        await this.props.getTemplates()
        await this.props.getResourceTags()
        this.setState({
            resourcesLoaded: true
        })
    } catch (e) {
        // in case any function above causes error
    }
}