Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React fetch data in server before render

Tags:

reactjs

I'm new to reactjs, I want to fetch data in server, so that it will send page with data to client.

It is OK when the function getDefaultProps return dummy data like this {data: {books: [{..}, {..}]}}.

However not work with code below. The code execute in this sequence with error message "Cannot read property 'books' of undefined"

  1. getDefaultProps
  2. return
  3. fetch
  4. {data: {books: [{..}, {..}]}}

However, I expect the code should run in this sequence

  1. getDefaultProps
  2. fetch
  3. {data: {books: [{..}, {..}]}}
  4. return

Any Idea?

statics: {     fetchData: function(callback) {       var me = this;        superagent.get('http://localhost:3100/api/books')         .accept('json')         .end(function(err, res){           if (err) throw err;            var data = {data: {books: res.body} }            console.log('fetch');                             callback(data);           });     }   getDefaultProps: function() {     console.log('getDefaultProps');     var me = this;     me.data = '';      this.fetchData(function(data){         console.log('callback');         console.log(data);         me.data = data;             });      console.log('return');     return me.data;               },     render: function() {     console.log('render book-list');     return (       <div>         <ul>         {           this.props.data.books.map(function(book) {             return <li key={book.name}>{book.name}</li>           })         }         </ul>       </div>     );   } 
like image 234
fingercross Avatar asked Jun 19 '15 03:06

fingercross


People also ask

How do you wait for data before render React?

React does not wait to render.There is no way to make it wait. All is not lost, though. There's an easy fix. Components that render async data need to be prepared to render an empty state, at least once.

How fetch data from server in React?

Using the JavaScript Fetch API. The Fetch API through the fetch() method allows us to make an HTTP request to the backend. With this method, we can perform different types of operations using HTTP methods like the GET method to request data from an endpoint, POST to send data to an endpoint, and more.

Does Componentdidmount happen before render?

componentWillMount() method is the least used lifecycle method and called before any HTML element is rendered. If you want to see then check out the example mentioned above, we just need to add one more method.


2 Answers

What you're looking for is componentWillMount.

From the documentation:

Invoked once, both on the client and server, immediately before the initial rendering occurs. If you call setState within this method, render() will see the updated state and will be executed only once despite the state change.

So you would do something like this:

componentWillMount : function () {     var data = this.getData();     this.setState({data : data}); }, 

This way, render() will only be called once, and you'll have the data you're looking for in the initial render.

like image 79
Michael Parker Avatar answered Sep 19 '22 12:09

Michael Parker


A very simple example of this

import React, { Component } from 'react'; import { View, Text } from 'react-native';  export default class App extends React.Component  {      constructor(props) {       super(props);        this.state = {         data : null       };     }      componentWillMount() {         this.renderMyData();     }      renderMyData(){         fetch('https://your url')             .then((response) => response.json())             .then((responseJson) => {               this.setState({ data : responseJson })             })             .catch((error) => {               console.error(error);             });     }      render(){         return(             <View>                 {this.state.data ? <MyComponent data={this.state.data} /> : <MyLoadingComponnents /> }             </View>         );     } } 
like image 22
Mahdi Bashirpour Avatar answered Sep 19 '22 12:09

Mahdi Bashirpour