Как отобразить данные, полученные от службы REST в React Universal? (Next.js)

Я хочу получать данные через сервисный вызов REST в приложении React Universal (с Next.js), используя fetch() и затем отобразить результат в 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 ответа

Решение

Чтобы заставить его работать, мне нужно было сделать 3 вещи:

  • замещать componentWillMount с помощью метода getInitialProps()
  • скомбинировать fetch с await и вернуть данные
  • использование 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>
  );
}

Можете добавить static async getInitialProps () {} загрузить данные в реквизит до того, как компонент страницы будет обработан.

Более подробная информация здесь: https://github.com/zeit/next.js/blob/master/readme.md#fetching-data-and-component-lifecycle

Другие вопросы по тегам