React 使用地图函数渲染一系列图像时遇到问题
我正在尝试设计一个组件,用户可以单击一个按钮,该按钮将触发 giphy API 调用,最终将呈现一系列 gif 图像。
到目前为止,除了实际的图像渲染之外,我能够成功完成所有工作。这是我目前的代码:
retrieveURLs() {
*bunch of stuff to make API call and return an array of URLs related
to the category of the button the user pushes*
}
renderGifs() {
this.retrieveURLs().then(function(results) {
console.log(results); //logs array of URLs
return results.map(function(url, index) {
console.log(url); //logs each url
return (<img key={index} src={url} alt="" />)
}, this);
});
}
render() {
return(
<div id="gif-div">
{this.renderGifs()}
</div>
)
}
尽管每个 console.log() 事件都表明 URL 至少已正确传递,但什么都没有呈现。
我对父组件做了类似的事情,以从如下所示的类别数组中呈现按钮:
btnArray = [*bunch of categories here*];
renderButtons() {
return btnArray.map(function(item, i) {
let btnID = btnArray[i].replace(/\s+/g, "+");
return <button type='button' className="btn btn-info" onClick={this.handleCategorySelect} key={i} id={btnID} value={btnID}>{btnArray[i]}</button>
}, this)
}
按钮可以正确呈现,但我的图像却不能。renderbuttons 和 rendergifs 方法都不会改变状态。老实说,我看不出两者之间有什么有意义的区别,所以我想得到一些帮助,弄清楚为什么一个有效而另一个无效。
这是异步函数的本质;您无法从回调中将值返回到原始调用站点。如果您要编写:
const res = this.retrieveURLs().then(function(results) {
return results;
});
您只会更改承诺的解析值。
res
不会被分配
results
的值,而是会被分配由
this.retrieveURLs()
创建的
promise
,并且检索已解析承诺的值的唯一方法是附加
.then
回调。
您可以这样做:
this.retrieveURLs().then(results => {
this.setState({ images: results });
});
现在您的内部状态将异步更新,并且您的组件将被告知使用新数据重新渲染,您可以通过访问状态在渲染函数中使用这些数据。
注意:
我在上面的示例中使用箭头函数来创建回调,因为否则
this
将不会绑定到正确的上下文。或者,您可以使用旧的
that = this
技巧,或使用
Function#bind
。
问题在于图像的渲染函数,以及反应确实在以前和当前状态之间差异的方式。由于获取是异步的,并且渲染不是,因此当获取完成后,React不知道它需要重新渲染您的组件。在这种情况下,有多种方法可以强制重新渲染,但是更好的解决方案是使用已经是
showerupdate
检查的功能。
您的实现可能会更改以查看类似以下内容:
608821887
我还会为不良结果,缺少键/值等处理一些处理。我希望我能对您有用,如果不让我知道! :)
首先,您忘记了返回语句:
renderGifs() {
return this.retrieveURLs().then(function(results) {
...
}
但这不会解决任何问题,因为它返回的是
Promise
。
您需要将请求结果保存在状态中,然后映射它:
constructor(props){
super(props);
this.state = { images: [] };
}
componentDidMount() {
this.renderGifs();
}
renderGifs() {
this.retrieveURLs().then(function(results) {
console.log(results); //logs array of URLs
this.stateState({ images: results });
});
}
render() {
return(
<div id="gif-div">
{
this.state.images.map((url, index) => (<img key={index} src={url} alt="" />);
}
</div>
)
}