14

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

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

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

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

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

谢谢

4

2 回答 2

16

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

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

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>

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

组件渲染数据

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

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

正如你在这个例子中看到的那样,moviesjson 只是被传递给 render:

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

然后,借助框架的魔力,可能在这一行中,为您的组件提供了信息,然后列表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.

对于非常好奇的人:

事实上,正如我们在这一行开始看到的那样,引擎合并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));
于 2016-05-23T07:55:19.840 回答
0

与 express(和任何其他视图渲染节点框架)一起工作的 react-engine 的替代方法是 react-helper(https://github.com/tswayne/react-helper)。它几乎可以处理您在任何节点框架中为您呈现反应组件所需的一切。您只需为 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}))

于 2017-04-03T18:09:54.050 回答