开发者问题收集

React 使用地图函数渲染一系列图像时遇到问题

2017-09-04
1180

我正在尝试设计一个组件,用户可以单击一个按钮,该按钮将触发 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 方法都不会改变状态。老实说,我看不出两者之间有什么有意义的区别,所以我想得到一些帮助,弄清楚为什么一个有效而另一个无效。

3个回答

这是异步函数的本质;您无法从回调中将值返回到原始调用站点。如果您要编写:

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

philraj
2017-09-04

问题在于图像的渲染函数,以及反应确实在以前和当前状态之间差异的方式。由于获取是异步的,并且渲染不是,因此当获取完成后,React不知道它需要重新渲染您的组件。在这种情况下,有多种方法可以强制重新渲染,但是更好的解决方案是使用已经是 showerupdate 检查的功能。

您的实现可能会更改以查看类似以下内容:

608821887

我还会为不良结果,缺少键/值等处理一些处理。我希望我能对您有用,如果不让我知道! :)

blackeyebeefhorsefly
2017-09-04

首先,您忘记了返回语句:

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>
    )
}
Tomasz Mularczyk
2017-09-04