Reactjs async rendering of components

≯℡__Kan透↙ 提交于 2019-11-26 12:21:19

问题


I want to render my component after my ajax request is done.

Below you can see my code

var CategoriesSetup = React.createClass({

    render: function(){
        var rows = [];
        $.get(\'http://foobar.io/api/v1/listings/categories/\').done(function (data) {
            $.each(data, function(index, element){
                rows.push(<OptionRow obj={element} />);
            });
           return (<Input type=\'select\'>{rows}</Input>)

        })

    }
});

But i get the error below because i am returning render inside the done method of my ajax request.

Uncaught Error: Invariant Violation: CategoriesSetup.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.

Is there a way to wait for my ajax request to end before start rendering?


回答1:


There are two ways to handle this, and which you choose depends on which component should own the data and the loading state.

  1. Move the Ajax request into the parent and conditionally render the component:

    var Parent = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <CategoriesSetup data={this.state.data} />;
        }
    
        return <div>Loading...</div>;
      }
    });
    
  2. Keep the Ajax request in the component and render something else conditionally while it's loading:

    var CategoriesSetup = React.createClass({
      getInitialState: function() {
        return { data: null };
      },
    
      componentDidMount: function() {
        $.get('http://foobar.io/api/v1/listings/categories/').done(function(data) {
          this.setState({data: data});
        }.bind(this));
      },
    
      render: function() {
        if (this.state.data) {
          return <Input type="select">{this.state.data.map(this.renderRow)}</Input>;
        }
    
        return <div>Loading...</div>;
      },
    
      renderRow: function(row) {
        return <OptionRow obj={row} />;
      }
    });
    



回答2:


The basic example of async rendering of components is below:

import React                from 'react';
import ReactDOM             from 'react-dom';        
import PropTypes            from 'prop-types';

export default class YourComponent extends React.PureComponent {
    constructor(props){
        super(props);
        this.state = {
            data: null
        }       
    }

    componentDidMount(){
        const data = {
                optPost: 'userToStat01',
                message: 'We make a research of fetch'
            };
        const endpoint = 'http://example.com/api/phpGetPost.php';       
        const setState = this.setState.bind(this);      
        fetch(endpoint, {
            method: 'POST',
            body: JSON.stringify(data)
        })
        .then((resp) => resp.json())
        .then(function(response) {
            setState({data: response.message});
        });
    }

    render(){
        return (<div>
            {this.state.data === null ? 
                <div>Loading</div>
            :
                <div>{this.state.data}</div>
            }
        </div>);
    }
}


来源:https://stackoverflow.com/questions/27192621/reactjs-async-rendering-of-components

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