score:0

first of all you forgot the return statement:

rendergifs() {
    return this.retrieveurls().then(function(results) {
...
}

but this won't solve anything as it is returning a promise.

you need to save request results in the state and then map it:

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>
    )
}

score:2

the problem lies with the rendering function for the images and the way react does diffing between the previous and current state. since the fetch is asynchronous and the render is not, when the fetch is completed react doesn't know that it needs to re-render you component. there are ways to force a re-render in this case, but a better solution is to use the functionality that's already part of the shouldupdate check.

your implementation might change to look something like the following:

class images extends component {
  state = {
    images: [],
    error: null
  }

  componentdidmount() {
    return this.retrieveimages()
      .then(images => this.setstate({images}))
      .catch(error => this.setstate({error}))
  }

  ... rest of your class definition

  render () {
    return (
      <div>
        {this.state.images.map(image => <img src={image.url} />)}
      </div>
    )
  }
}

i would also have some handling for bad results, missing key / values, etc. i hope that works for you, if not let me know! :)

score:3

this is the nature of asynchronous functions; you can't return a value from within a callback to the original call site. if you were to write:

const res = this.retrieveurls().then(function(results) {
    return results;
});

you'd only be changing the resolution value of the promise. res won't be assigned the value of results, but rather it will be assigned the promise created by this.retrieveurls(), and the only way to retrieve the value of a resolved promise is by attaching a .then callback.


what you could do is this:

this.retrieveurls().then(results => {
    this.setstate({ images: results });  
});

now your internal state will be updated asynchronously, and your component will be told to re-render with the new data, which you can use in your render function by accessing the state.

note: i'm using an arrow function to create the callback in the above example, because otherwise this won't be bound to the right context. alternatively, you could do the old that = this trick, or use function#bind.


Related Query

More Query from same tag