我有一个React应用程序,通过Express进行服务器端渲染。我有简单的App组件:
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>
);
}
};
问题(或更可能的功能)是fetch工作异步。因此浏览器获取包含空数据的页面。
有没有办法从带有加载数据的服务器页面获取?让我们说我想从服务器页面获取加载的帖子或其他东西。
或者我有什么不对劲?
答案 0 :(得分:0)
您没有正确设置state
。使用setState()
设置新状态,因为您无法使用setState()
方法更新状态: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}));
此外,您添加的代码不是使用React的服务器端呈现。您使用方法ReactDOMServer.renderToString()
进行服务器端呈现:https://facebook.github.io/react/docs/react-dom-server.html#rendertostring
答案 1 :(得分:0)
是的,即使你修复了setState()问题,你仍然会在获取之前渲染组件。问题确实是fetch是异步的。
为了能够在服务器端渲染后端调用,您需要等到所有后端调用完成后,设置道具&amp;所有组件的状态,然后将它们渲染出来。
如果您使用的是Redux,那么可以帮助您确定何时完成任务的两个库是Redial(https://github.com/markdalgleish/redial)和redux-promise-counter(https://github.com/bitgenics/redux-promise-counter)。更多关于以下内容。
您要解决的下一个问题是将数据传输到客户端并从中初始化您的组件,这样您就不必再次在客户端上重做(全部)请求。
你可以手动完成所有这些工作,但如果你认真对待SSR,你应该选择像Redux这样的东西。一种将所有应用程序状态存储在一个商店中的方法。使结果更容易存储,将其发送到客户端并从JSON初始化您的商店。