【问题标题】:Server-side variables to Client-Side with React-Engine and Express使用 React-Engine 和 Express 将服务器端变量传递到客户端
【发布时间】:2016-09-18 11:55:55
【问题描述】:

我对 React/React-Engine 相当陌生。我在服务器端有一个配置,我需要将某些值传递给客户端,但是我依赖 NODE_ENV 才能获得正确的配置。

var config = {
    local: { ... }
    production: { ...}
}

module.exports = config[process.env.NODE_ENV]

这在服务器端工作得很好,但是因为我需要在客户端引用这些对象中包含的一些值,所以我不能 require(./config);在我的 React JSX 中。

有没有什么简单的方法可以将这些东西传递到 React 中?归根结底,如果我能以某种方式直接将“配置”传递给 React,我会很高兴,甚至不必担心客户端的 NODE_ENV。

谢谢

【问题讨论】:

    标签: express reactjs react-engine


    【解决方案1】:

    react-helper (https://github.com/tswayne/react-helper) 可以很好地与 express(以及任何其他视图渲染节点框架)配合使用,以替代 react-engine。它几乎可以处理您在任何节点框架中为您呈现反应组件所需的一切。您只需为 webpack 创建一个入口点(js 文件)(它可以为您生成 webpack 配置)并在您的控制器和视图中添加一行,您的组件将在该页面上呈现。您还可以将数据从 express 传递给您的 react 组件,当组件在您的浏览器中绑定时,它将可以访问该服务器端数据。

    const component = reactHelper.renderComponent('MyComponent', {prop: config.prop}) res.render('view-to-render', {component})

    还有用于 react-helper (https://github.com/tswayne/express-react-helper) 的快速中间件,它允许您添加可用于所有视图的上下文,方便配置数据。

    app.use(expressReactHelper.addToReactContext({configProp: config.foo}))

    【讨论】:

      【解决方案2】:

      在渲染之前将数据从服务器传递到客户端的最常见方法是将数据嵌入到 React 正在渲染的页面上的全局 JavaScript 变量中。

      因此,例如,在中间件中,您实际上正在渲染一些模板,其中包含您的 React 应用程序中的 <script> 标签,您可以添加信息并在模板​​上抓取它:

      var config = require('../config-from-somewhere');
      app.get('/', function (req, res) {
        res.render('index', {config: JSON.stringify(config)});
      });
      

      还有一个小胡子模板示例:

      <html>
      <body>
      <script>
        window.CONFIG = JSON.parse({{{config}}});
      </script>
      <script src="my-react-app.js"/> 
      </body>
      </html>
      

      但是显然react-engine 已经提供了自己的方式来在客户端发送数据:

      组件渲染数据

      输入组件进行渲染的实际数据是 express 生成的 renderOptions 对象。

      https://github.com/paypal/react-engine#data-for-component-rendering

      正如您在this example 中看到的那样,movies json 只是被传递到渲染中:

      app.get('*', function(req, res) {
        res.render(req.url, {
          movies: require('./movies.json')
        });
      });
      

      然后,借助框架的魔力,可能在this line 上,为您的组件提供信息,然后List 使用来自props.movies 的信息。

      module.exports = React.createClass({
        displayName: 'List',
      
        render: function render() {
          return (
            <div id='list'>
              <h1>Movies</h1>
              <h6>Click on a movie to see the details</h6>
              <ul>
                {this.props.movies.map(function(movie) {
                  return (
                    <li key={movie.id}>
                      <Router.Link to={'/movie/' + movie.id}>
                        <img src={movie.image} alt={movie.title} />
                      </Router.Link>
                    </li>
                  );
                })}
      
              </ul>
            </div>
          );
        }
      });
      

      所以,基本上将您的config 添加到您的渲染调用,它应该在您的组件的props 中可用。

      对于非常好奇的人:

      确实,正如我们在 this line onwards 上看到的那样,引擎合并了 renderOptionsres.locals,并最终将其传递给 React。

      // create the data object that will be fed into the React render method.
      // Data is a mash of the express' `render options` and `res.locals`
      // and meta info about `react-engine`
      var data = merge({
        __meta: {
          // get just the relative path for view file name
          view: null,
          markupId: Config.client.markupId
        }
      }, omit(options, createOptions.renderOptionsKeysToFilter));
      

      还有:

      return React.createElement(Component, merge({}, data, routerProps));
      

      【讨论】:

      • 谢谢!解决方案一直在我的眼皮底下。 :) 下一个问题是我是否可以在 React.createClass({..}) 之外访问“配置”,因为数据是通过 props 传递的。
      • 您能否就此提出一个新问题并接受此解决方案?
      • 使用像“window.CONFIG =”这样的javascript变量是安全的吗?那么 XSS 呢?谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-14
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      相关资源
      最近更新 更多