我的目标是提出一系列请求,并在完成每个请求后更新指示当前正在处理哪个步骤的文本。像这样:
在我介绍细节之前,我想先解决一下,据我所知有两种触发重新渲染的方法
setState
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 );
}
} );
};
文件已成功下载,但是我无法在两次请求之间重新渲染该组件。即使状态中的文本确实已经更新,如我已经输出的控制台消息所示,
我曾尝试在多个不同的位置插入forceUpdate
,但总的来说,如果我到达需要尝试使用forceUpdate
的地步,那是行不通的。< / p>
答案 0 :(得分:3)
您应该尝试在processRequests调用中使用setState回调处理程序函数。
它将等待setState完成并且组件重新渲染,然后再调用下一个文件下载功能。
this.setState( { processing_text: message }, () => {
this.requestFileAndDownload( url, callback ).then( () => {
if( requests.length ) {
this.processRequests( requests );
}
});
});