简体   繁体   中英

React server side rendering with backend requests

I have an React app with server side rendering via Express. I have simple App component:

import React, { Component } from 'react';

export default class App extends Component {
  constructor(props) {
    super(props)

    this.state = {
      data: []
    };

    fetch('http://backend', {
      mode: 'cors',
    })  
      .then(res => res.json())
      .then(data => this.state.data); 
  }

  render() {
    return (
      <ul> 
        {this.state.data.map(item => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    );
  }
};

The problem (or more probable feature) is that fetch works async. So browser gets page with empty data.

Is there a way to get from server page with loaded data? Let's say I want to get from server page with loaded posts or something else.

Or do I something wrong at all?

You are not setting the state correctly. Use setState() to set the new state as you cannot update the state without using setState() method: https://facebook.github.io/react/docs/react-component.html#setstate

fetch('http://backend', {
  mode: 'cors',
})  
.then(res => res.json())
.then(data => this.setState({data: data})); 

Also, the code you have added is not server-side rendering using React. You use the method ReactDOMServer.renderToString() to do server-side rendering: https://facebook.github.io/react/docs/react-dom-server.html#rendertostring

Yes, even if you fix the setState() problem you will still be rendering the component before the fetch. The problem is indeed that fetch is asynchronous.

To be able to server-side render back-end calls you need to wait until all backend calls have been made, set the props & state for all components and then render them out.

Two libraries that will help you with figuring out when things are done are Redial ( https://github.com/markdalgleish/redial ) and redux-promise-counter ( https://github.com/bitgenics/redux-promise-counter ) if you are using Redux. More on that below.

The next problem you want to solve is getting that data to the client and initialize your components from that, so you don't have to redo (all) the request(s) on the client again.

You could do all that manually, but if you are serious about SSR, you should probably go for something like Redux. A way to store all your application state in one store. Makes it easier to store results, ship it to the client and initialize your store from JSON.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM