node.js - 我可以用 React 中的数据进行服务器渲染吗?

标签 node.js reactjs

我最近正在研究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/

相关文章:

reactjs - 无法访问主题的 Material-ui 中的 pxToRem 函数

node.js - 从 Nodemailer 到 Postfix 的加密连接失败,出现 "SSL23_GET_SERVER_HELLO:unknown protocol"

node.js - "Attribute ' 程序 ' does not exist"用于基本 node.js 项目

javascript - 如何处理异步循环函数中的await调用-nodejs

javascript - 为什么日期对象中有值时显示为空?

reactjs - 使用按钮上传 Material-UI 文件

reactjs - 如何在 useEffect 中使用 prop 值而不将其添加到依赖项数组中?

javascript - 未定义的查询函数

node.js - Node.js 模块 'time' 的时区问题

javascript - 在 ReactJS 中每次重新渲染时获取一个新的 FabricJS-Canvas