Server-side variables to Client-Side with React-Engine and Express

匆匆过客 提交于 2019-12-03 11:49:02

问题


I'm reasonably new to React/React-Engine. I have a config on the server-side that I need to pass certain values of to client-side however I have a dependency on NODE_ENV in order to get the correct config out.

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

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

Which works just fine server-side, however since I need to reference some of values contained in these objects on the client-side so I can't require(./config); in my React JSX.

Is there any easy way to pass this stuff into React? At the end of the day, I'd be happy if I could just pass the 'config' straight into React somehow without even having to worry about NODE_ENV on the client-side.

Thanks


回答1:


The most common way to pass data from the server to client before rendering is to embed it in a global JavaScript variable on the page where your React is rendering.

So, for example, in the middleware where you're actually rendering some template which includes your <script> tags with your React app, you could add the info and grab it on the template:

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

And an example mustache template:

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

HOWEVER apparently react-engine already provides its own way to send data do the client-side:

Data for component rendering

The actual data that gets fed into the component for rendering is the renderOptions object that express generates.

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

As you can see in this example, the movies json is simply being passed into render:

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

And then, by the grace of the framework's magic, probably on this line, the information is provided for your components and then the List uses it from 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>
    );
  }
});

So, basically add your config to your render call and it should be available in your component's props.

And for the very curious:

Indeed, as we can see on this line onwards, the engine merges renderOptions and res.locals and finally passes that down to 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));

And:

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



回答2:


An alternative to react-engine that works well with express (and any other view rendering node framework) is react-helper (https://github.com/tswayne/react-helper). It pretty much handles everything you need to do to render react components for you in any node framework. You just make an entry point (js file) for webpack (it can generate your webpack config for you) and add a line to your controller and view and your component will render on that page. You can also pass data to your react component from express and when the component binds in your browser it will have access to that server-side data.

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

There is also express middleware for react-helper (https://github.com/tswayne/express-react-helper) that allows you to add context that is available to all views, which is convenient for config data.

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



来源:https://stackoverflow.com/questions/37359872/server-side-variables-to-client-side-with-react-engine-and-express

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!