简体   繁体   中英

How to render data received from a REST service in React Universal? (Next.js)

I want to receive data via a REST service call in my React Universal (with Next.js) app using fetch() and then render the result into JSX like this:

class VideoPage extends Component {
  componentWillMount() {
    console.log('componentWillMount');

    fetch(path, {
      method: 'get',
    })
      .then(response =>
        response.json().then(data => {
          this.setState({
            video: data,
          });
          console.log('received');
        })
      );
  }

  render() {
    console.log('render');
    console.log(this.state);
    if (this.state && this.state.video) {
      return (
        <div>
          {this.state.video.title}
        </div>
      );
    }
  }
}

export default VideoPage;

Unfortunately, the output is this:

componentWillMount
render
null
received

Which does make sense because the call to fetch is asynchronously and render() finishes before the call to the REST service has finished.

In a client-side app this would be no problem because a change of state would call render() which then updates the view, but in a universal app, especially with JavaScript turned off on the client, this is not possible.

How can I solve this?

Is there a way to call the server synchronously or delay render() ?

In order to get it working, I had to do 3 things:

  • Replace componentWillMount with getInitialProps() method
  • Combine fetch with await and return the data
  • Use this.props instead of this.state

Code looks like this now:

static async getInitialProps({ req }) {
  const path = 'http://path/to/my/service';
  const res = await fetch(path);
  const json = await res.json();
  return { video: json };
}

Then, in render() I can access the data via this.props.video , for example:

render() {
  return (
    <div>{this.props.video.title}</div>
  );
}

You can add static async getInitialProps () {} to load data into props before the page component gets rendered.

More info here: https://github.com/zeit/next.js/blob/master/readme.md#fetching-data-and-component-lifecycle

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