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?
The mental model of React Async is component-first. Rather than loading data high up in your application and passing it down to a component for display, you perform the data loading at the component level. Such a component is called an async component.
With Suspense, you have the ability to suspend component rendering while async data is being loaded. You can pause any state update until the data is ready, and you can add async loading to any component deep in the tree without plumbing all the props and state through your app and hoisting the logic.
React components automatically re-render whenever there is a change in their state or props. A simple update of the state, from anywhere in the code, causes all the User Interface (UI) elements to be re-rendered automatically.
There are two ways to handle this, and which you choose depends on which component should own the data and the loading state.
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>; } });
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} />; } });
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>); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With