如何在React Universal中呈现从REST服务接收的数据? (Next.js)

时间:2017-05-04 21:33:55

标签: node.js reactjs react-jsx next.js react-universal

我希望使用fetch()在我的React Universal(使用Next.js)应用程序中通过REST服务调用接收数据,然后将结果呈现为JSX,如下所示:

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;

不幸的是,输出是这样的:

componentWillMount
render
null
received

这是有意义的,因为对fetch的调用是异步的,render()在调用REST服务之前完成。

在客户端应用程序中这没有问题,因为更改状态会调用render()然后更新视图,但在通用应用程序中,尤其是在客户端关闭JavaScript时,这不是可能的。

我该如何解决这个问题?

有没有办法同步调用服务器或延迟render()

2 个答案:

答案 0 :(得分:1)

为了让它发挥作用,我必须做三件事:

  • componentWillMount替换为getInitialProps()方法
  • fetchawait合并并返回数据
  • 使用this.props代替this.state

代码现在看起来像这样:

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

然后,在render()我可以通过this.props.video访问数据,例如:

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

答案 1 :(得分:0)

您可以添加static async getInitialProps () {}以在呈现页面组件之前将数据加载到props中。

此处有更多信息:https://github.com/zeit/next.js/blob/master/readme.md#fetching-data-and-component-lifecycle