如何强制组件在同步请求之间重新渲染? (React Native)

时间:2019-01-09 20:49:00

标签: javascript reactjs react-native

我的目标是提出一系列请求,并在完成每个请求后更新指示当前正在处理哪个步骤的文本。像这样:

Screenshot

在我介绍细节之前,我想先解决一下,据我所知有两种触发重新渲染的方法

  1. 使用setState
  2. 使用forceUpdate(不推荐)

这两种方法都不适合我,这就是为什么我要创建这个问题。

据我了解,异步请求中的更新状态存在触发重新渲染的问题。因此,我尝试使用此处底部的递归方法processRequests同步处理每个异步请求:

process = () => {
    this.setState( { processing: true } );

    const dir = RNFetchBlob.fs.dirs.MainBundleDir;

    const { item } = this.state;

    const requests = [
        {
            url: `${this.base_url}/${item.id}`,
            message: 'Loading model...',
            callback: function( res ) {
                return new Promise( resolve => {
                    const model_url = JSON.parse( res.data );
                    RNFetchBlob.config( {
                        path : `${dir}/model.obj`
                    } ).fetch( 'GET', model_url ).then( () => resolve() )
                } );
            }
        },
        {
            url: `${this.base_url}/${item.id}`,
            message: 'Loading texture...',
            callback: function( res ) {
                return new Promise( resolve => {
                    const texture_url = JSON.parse( res.data );
                    const split = texture_url.split( '.' );
                    const extension = split[ split.length -1 ];
                    RNFetchBlob.config( {
                        path : `${dir}/texture.${extension}`
                    } ).fetch( 'GET', texture_url ).then( () => resolve() )
                } );
            }
        }
    ];

    this.processRequests( requests );
};

requestFileAndDownload = ( url, callback ) => {
    return new Promise( resolve => {
        RNFetchBlob.fetch( 'GET', url ).then( res => {
            callback( res ).then( () => {
                resolve();
            } )
        } );
    } );
};

processRequests = requests => {
    const request = requests.shift();

    const { url, message, callback } = request;

    console.log( 'message = ', message );

    this.setState( { processing_text: message } );

    this.requestFileAndDownload( url, callback ).then( () => {
        if( requests.length ) {
            this.processRequests( requests );
        }
    } );
};

文件已成功下载,但是我无法在两次请求之间重新渲染该组件。即使状态中的文本确实已经更新,如我已经输出的控制台消息所示,

Screenshot

我曾尝试在多个不同的位置插入forceUpdate,但总的来说,如果我到达需要尝试使用forceUpdate的地步,那是行不通的。< / p>

1 个答案:

答案 0 :(得分:3)

您应该尝试在processRequests调用中使用setState回调处理程序函数。

它将等待setState完成并且组件重新渲染,然后再调用下一个文件下载功能。

this.setState( { processing_text: message }, () => {
  this.requestFileAndDownload( url, callback ).then( () => {
    if( requests.length ) {
        this.processRequests( requests );
    }
  });
});