Как отобразить данные, полученные от службы 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