Серверные переменные на стороне клиента с React-Engine и Express

Я новичок в React/React-Engine. У меня есть конфиг на стороне сервера, что мне нужно передать определенные значения для клиентской стороны, однако у меня есть зависимость от NODE_ENV, чтобы получить правильную конфигурацию.

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

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

Что работает просто отлично на стороне сервера, однако, поскольку мне нужно ссылаться на некоторые из значений, содержащихся в этих объектах на стороне клиента, поэтому я не могу требовать (./config); в моем React JSX.

Есть ли простой способ передать этот материал в React? В конце дня я был бы счастлив, если бы смог просто передать "конфиг" прямо в React, даже не беспокоясь о NODE_ENV на стороне клиента.

Спасибо

Ответ 1

Самый распространенный способ передачи данных с сервера клиенту перед его рендерингом - вставить его в глобальную переменную 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>

ОДНАКО, очевидно react-engine уже предоставляет свой собственный способ отправки данных на стороне клиента:

Данные для рендеринга компонентов

Фактические данные, которые передаются в компонент для рендеринга, представляют собой объект renderOptions, который выражает.

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

Как вы можете видеть в в этом примере, movies json просто передается в render:

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

И затем, по милости магии рамки, вероятно, на этой строке, информация предоставляется для ваших компонентов, а затем 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.

И для очень любопытных:

В самом деле, как мы можем видеть на этой строке далее, двигатель объединяет renderOptions и res.locals и, наконец, передает это, чтобы Реагировать.

// 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));

Ответ 2

Альтернатива реактивному движку, который хорошо работает с выражением (и любым другим представлением рендеринга node), - это реакция-помощник (https://github.com/tswayne/react-helper). Он в значительной степени обрабатывает все необходимое для рендеринга компонентов для вас в любой инфраструктуре node. Вы просто создаете точку входа (js файл) для webpack (он может генерировать вашу конфигурацию webpack для вас) и добавляйте строку к контроллеру и просматривайте, и ваш компонент будет отображаться на этой странице. Вы также можете передавать данные на свой компонент реагирования из экспресс, и когда компонент связывается в вашем браузере, он будет иметь доступ к данным на стороне сервера.

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

Существует также выраженное промежуточное ПО для реагирования-помощника (https://github.com/tswayne/express-react-helper), что позволяет добавлять контекст, доступный для всех представлений, что удобно для данных конфигурации.

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