使用render方法内的promises渲染React组件 [英] Rendering React components with promises inside the render method
问题描述
我有一个组件,它将一个项目集合作为道具, map
将它们作为一个组件集合,这些组件呈现为父组件的子组件。我们使用存储在 WebSQL
中的图像作为字节数组。在 map
函数中,我从项目中获取图像ID并对 DAL
进行异步调用以获取图像的字节数组。我的问题是我无法将承诺传播到React,因为它不是为了处理渲染中的承诺而设计的(不管怎样我都不知道)。我来自 C#
背景,所以我想我正在寻找像 await
这样的关键词进行重新同步分支代码。
I have a component which gets a collection of items as props and map
s them to a collection of components which are rendered as children of a parent component. We use images stored in WebSQL
as byte arrays. Within the map
function I get an image Id from the item and make an async call to the DAL
in order to get the byte array for the image. My problem is that I cannot propagate the promise in to React, since it was not designed to deal with promises in rendering (not as far as I can tell anyway). I come from a C#
background, so I guess I'm looking for something like the await
keyword for resync-ing branched code.
map
函数看起来像这样(简化):
The map
function looks something like this (simplified):
var items = this.props.items.map(function (item) {
var imageSrc = Utils.getImageUrlById(item.get('ImageId')); // <-- this contains an async call
return (
<MenuItem text={item.get('ItemTitle')}
imageUrl={imageSrc} />
);
});
和 getImageUrlById
方法如下所示:
getImageUrlById(imageId) {
return ImageStore.getImageById(imageId).then(function (imageObject) { //<-- getImageById returns a promise
var completeUrl = getLocalImageUrl(imageObject.StandardConImage);
return completeUrl;
});
}
这不起作用,但我不知道我需要什么修改使这项工作。我尝试向链添加另一个promise,但后来我得到一个错误,因为我的render函数返回一个promise而不是合法的JSX。我在想,也许我需要利用其中一个 React
生命周期方法来获取数据,但因为我需要 props
已经在那里,我无法弄明白我能做到这一点。
This doesn't work, but I don't know what I need to modify to make this work. I tried adding another promise to the chain, but then I get an error because my render function return a promise instead of legal JSX. I was thinking that maybe I need to leverage one of the React
life-cycle methods to fetch the data, but since I need the props
to already be there, I can't figure out where I can do this.
推荐答案
render()
方法应该从this.props和this.state呈现UI,所以要异步加载数据,你可以使用 this.state
存储 imageId:imageUrl
映射。
然后在你的 componentDidMount()
方法中,你可以从imageId填充imageUrl。然后通过渲染 this.state
对象
render()
method should render UI from this.props and this.state, so to async load data, You can use this.state
to store imageId:imageUrl
mapping.
Then in your componentDidMount()
method, you can populate imageUrl from imageId. Then the render()
method should be pure and simple by rendering the this.state
object
以下是一个快速示例代码:
请注意 this.state.imageUrls
是异步填充的,所以获取其URL后,渲染图像列表项将逐一显示。您还可以使用所有图像ID或索引(不带网址)初始化 this.state.imageUrls
,这样您就可以在加载图像时显示加载程序。
Here is a quick sample code:
Note that the this.state.imageUrls
is populated asynchronously, so the rendered image list item will appear one by one after its url is fetched. You can also initialize the this.state.imageUrls
with all image id or index (without urls), this way you can show a loader when that image is being loaded.
constructor(props) {
super(props)
this.state = {
imageUrls: []
};
}
componentDidMount() {
var self = this;
this.props.items.map((item) => {
ImageStore.getImageById(item.imageId).then(image => {
var mapping = {id: item.imageId, url: image.url};
var newUrls = self.state.imageUrls.slice();
newUrls.push(mapping);
self.setState({
imageUrls: newUrls
});
})
});
}
render() {
return (<div>
this.state.imageUrls.forEach(mapping => {
<div>id: {mapping.id}, url: {mapping.url}`</div>
})
</div>
);
}
这篇关于使用render方法内的promises渲染React组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!