我最近正在研究react。我正在使用react-router进行服务器渲染,但它只能从react组件渲染HTML,并且我需要在componentDidMount()
中通过ajax获取初始数据。
问题在于某些页面/组件,它们需要初始数据才能呈现。因此,如果用户直接访问这样的页面(通过输入 url 或刷新),页面就会损坏,因为服务器无法在没有初始数据的情况下呈现它。
我在想我可以从数据库获取数据并在服务器渲染时将其插入模板吗?就像经典的前端模板或 PHP 所做的那样。
如果没有办法,渲染首页数据的最佳实践是什么?
现在我的服务器代码如下:
router.get('*', function(req, res) {
console.log('GET ADMIN');
match({
routes: appRoutes,
location: req.originalUrl
}, (error, redirectLocation, renderProps) => {
if (error) {
res.status(500)
.send(error.message);
} else if (redirectLocation) {
res.status(302)
.redirect(redirectLocation.pathname + redirectLocation.search);
} else if (renderProps) {
var content = renderToString(<RoutingContext {...renderProps}/>);
var html = swig.renderFile('src/client/admin.html', {
content: content
});
res.status(200)
.send(html);
} else {
res.status(404)
.send('Not found');
}
});
});
最佳答案
终于在GitHub上找到了答案:https://github.com/rackt/react-router/issues/1969#issuecomment-140988110
该方法将服务器渲染时需要的所有数据插入到HTML模板中,并在前端获取数据为context
。所有组件都可以通过 context
获取数据.
我使用<DataWrapper>
组件来包装原始的根应用程序组件。在服务器端渲染时:
data = JSON.stringify(data); // data is an object
ReactDOMServer.renderToString(<DataWrapper data={data}><RoutingContext {...renderProps}/></DataWrapper>)
和<DataWrapper>
是这样的:
import React from 'react';
class DataWrapper extends React.Component {
getChildContext () {
return {
data: this.props.data
};
}
render () {
return this.props.children;
}
}
DataWrapper.childContextTypes = {
data: React.PropTypes.object.isRequired
};
export default DataWrapper;
在客户端:
var data = JSON.parse(document.getElementById('data').innerHTML),
history = createBrowserHistory();
ReactDOM.render(<DataWrapper data={ data }><Router history={ history }>{ routes }</Router></DataWrapper>, document.getElementById('app'));
通过组件中的上下文获取数据:
class someComponent extends React.Component {
constructor (props, context) {
super(props, context);
this.state = context.data.someData;
}
}
someComponent.contextTypes = {
data: React.PropTypes.object.isRequired
};
export default someComponent;
效果很好
关于node.js - 我可以用 React 中的数据进行服务器渲染吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33542772/