Rendering react component after api response

眉间皱痕 提交于 2019-12-17 18:28:38

问题


I have a react component that I wish to populate with images using the Dropbox api. The api part works fine, but the component is rendered before the data comes through & so the array is empty. How can I delay the rendering of the component until it has the data it needs?

var fileList = [];
var images = [];
var imageSource = [];

class Foo extends React.Component {

 render(){
  dbx.filesListFolder({path: ''})
  .then(function(response) {
   fileList=response.entries;
   for(var i=0; i<fileList.length; i++){
    imageSource.push(fileList[0].path_lower);
   }
   console.log(imageSource);
   })

  for(var a=0; a<imageSource.length; a++){
   images.push(<img key={a} className='images'/>);
  }

  return (
   <div className="folioWrapper">
    {images}
   </div>
  );
 }
}

Thanks for your help!


回答1:


Changes:

1. Don't do the api call inside render method, use componentDidMount lifecycle method for that.

componentDidMount:

componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering.

2. Define the imageSource variable in state array with initial value [], once you get the response update that using setState, it will automatically re-render the component with updated data.

3. Use the state array to generate the ui components in render method.

4. To hold the rendering until you didn't get the data, put the condition inside render method check the length of imageSource array if length is zero then return null.

Write it like this:

class Foo extends React.Component {

    constructor(){
        super();
        this.state = {
            imageSource: []
        }
    }

    componentDidMount(){
        dbx.filesListFolder({path: ''})
          .then((response) => {
              let fileList = response.entries;
              this.setState({
                  imageSource: fileList
              });
          })
    }

    render(){
        if(!this.state.imageSource.length)
            return null;

        let images = this.state.imageSource.map((el, i) => (
            <img key={i} className='images' src={el.path_lower} />
        ))

        return (
            <div className="folioWrapper">
                {images}
            </div>
        );
    }
}



回答2:


You should be using your component's state or props so that it will re-render when data is updated. The call to Dropbox should be done outside of the render method or else you'll be hitting the API every time the component re-renders. Here's an example of what you could do.

class Foo extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      imageSource: []
    }
  }

  componentDidMount() {
    dbx.filesListFolder({ path: '' }).then(function(response) {
      const fileList = response.entries;

      this.setState({
        imageSource: fileList.map(file => file.path_lower);
      })
    });
  }

  render() {
    return (
      <div className="folioWrapper">
        {this.state.imageSource.map((image, i) => <img key={i} className="images" src={image} />)}
      </div>
    );
  }
}

If there are no images yet, it'll just render an empty div this way.




回答3:


First off, you should be using the component's state and not using globally defined variables.

So to avoid showing the component with an empty array of images, you'll need to apply a conditional "loading" class on the component and remove it when the array is no longer empty.



来源:https://stackoverflow.com/questions/44911012/rendering-react-component-after-api-response

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!