在React中渲染加载栏

时间:2017-03-30 21:04:27

标签: reactjs asynchronous promise

我的组件progress中有一个状态,我很担心生命周期中最佳时间何时更新progress状态我在componentDidMount()中发出http请求承诺。所以我希望在数据未准备好呈现时呈现进度条。

我正在使用Axios发出请求,我在该请求中创建了几个蓝鸟Promise。

最后,我将progress状态更新为100,

componentDidMount() {
    axios.get('/api/property/documents.json')
        .then((res) => {
            // save an object with the variable representation of the variable and the string
            // this will allow a forEach loop for teh promises of data
            let complianceStatus = {
                needsUploading: 'needsUploading',
                pendingApproval: 'pendingApproval',
                approved: 'approved'
            }

            function filterer(status, target) { return status === target }

            for(let status in complianceStatus) {
                let current = status;
                Promise.map(res.data.compliance, (record) => {
                    return Promise.all([filterer(record.type, complianceStatus[status]), record]);
                }).then((values) => {
                    status = values.filter((value) => {
                        return value[0] == true
                    }).map((value) => {
                        return value[1];
                    });
                    this.setState({ [complianceStatus[current]]: status })
                })
            }
            // general data 
            Promise.map(res.data.general, (record) => {
                    return record;
                }).then((generalDocs) => {
                    this.setState({ generalDocs })
                })
        }).then(() => {
            this.setState({ progress: 100, isLoading: false });
        })
        .catch((err) => {
            console.log(err);
        });
}

我的<ProgressBar percent={ this.state.progress } autoIncrement={ true } spinner={ false } />只是在我返回渲染方法时。

1 个答案:

答案 0 :(得分:0)

它不会超级准确,但你可以制作一些向用户展示正在发生进展的东西,并对目前为止的进展做一个粗略的了解。我已将进度条更新逻辑提取到类中的另一个函数中:

getProgressUpdater() {
    let maxTicks = 0;
    let currentTick = 0;
    let isTicking = false;

    const setTick = ( progress ) => {
        this.setState({ progress });
    }

    const tick = () => {
        setTick(++currentTick);
        if( currentTick < maxTicks ) {
            isTicking = true;
            setTimeout(tick, 100);
        } else {
            isTicking = false;
        }
    }

    const setMaxTicks = ( progress ) => {
         maxTicks = progress;
         if (!isTicking) {
             tick();
         }
    }

    const incrementMaxTicks = ( increment ) => {
         maxTicks += increment;
         if (!isTicking) {
             tick();
         }
    }

    return {
         setMaxTicks,
         incrementMaxTicks,
         setTick
    }
}

您可以在整个异步调用中使用它来提供进度更新:

componentDidMount() {
  const progressUpdater = this.getProgressUpdater();
  progressUpdater.setMaxTicks(10);
  axios.get('/api/property/documents.json')
    .then((res) => {
        // save an object with the variable representation of the variable and the string
        // this will allow a forEach loop for teh promises of data
        let complianceStatus = {
            needsUploading: 'needsUploading',
            pendingApproval: 'pendingApproval',
            approved: 'approved'
        }

        function filterer(status, target) { return status === target }

        for(let status in complianceStatus) {
            progressUpdater.incrementMaxTicks(25);
            let current = status;
            Promise.map(res.data.compliance, (record) => {
                return Promise.all([filterer(record.type, complianceStatus[status]), record]);
            }).then((values) => {
                status = values.filter((value) => {
                    return value[0] == true
                }).map((value) => {
                    return value[1];
                });
                this.setState({ [complianceStatus[current]]: status })
            })
        }


        progressUpdater.setMaxTicks(90)

        // general data 
        Promise.map(res.data.general, (record) => {
                return record;
            }).then((generalDocs) => {
                this.setState({ generalDocs })
            })
    }).then(() => {
        progressUpdater.setTick(100);
    })
    .catch((err) => {
        console.log(err);
    });
}