Использование React в многостраничном приложении

Я играл с React, и до сих пор мне это очень нравится. Я создаю приложение с NodeJS и хотел бы использовать React для некоторых интерактивных компонентов в приложении. Я не хочу делать это одностраничное приложение.

Я еще ничего не нашел в интернете, которые отвечают на следующие вопросы:

как разбить или связать мои компоненты React через многостраничное приложение?

в настоящее время все мои компоненты в один файл, хотя я никогда не могу загрузить их в некоторых разделах приложения.

до сих пор я пытаюсь использовать условные операторы для рендеринга компонентов, ища идентификатор контейнера, где React будет рендерить. Я не на 100% уверен в том, что лучшие практики с React. Выглядит примерно так.

if(document.getElementById('a-compenent-in-page-1')) {
    React.render(
        <AnimalBox url="/api/birds" />,
        document.getElementById('a-compenent-in-page-1')
    );
}

if(document.getElementById('a-compenent-in-page-2')) {
    React.render(
        <AnimalBox url="/api/cats" />,
        document.getElementById('a-compenent-in-page-2')
    );
}

if(document.getElementById('a-compenent-in-page-3')) {
    React.render(
        <AnimalSearchBox url="/api/search/:term" />,
        document.getElementById('a-compenent-in-page-3')
    );
}

Я все еще читаю документацию и еще не нашел то, что мне нужно для многостраничного приложения.

спасибо заранее.

4 ответов


В настоящее время я делаю что-то подобное.

приложение не является полным приложением React, я использую React для динамических вещей, таких как CommentBox, который является autark. И может быть включен в любой момент с помощью специальных params..

тем не менее, все мои sub приложения загружаются и включаются в один файл all.js, поэтому он может быть кэширован браузером по страницам.

когда мне нужно включить приложение в Шаблоны SSR, мне просто нужно включить DIV с классом "__react-root " и специальный идентификатор (имя приложения React, которое будет отображаться)

логика очень проста:

import CommentBox from './apps/CommentBox';
import OtherApp from './apps/OtherApp';

const APPS = {
  CommentBox,
  OtherApp
};

function renderAppInElement(el) {
  var App = APPS[el.id];
  if (!App) return;

  // get props from elements data attribute, like the post_id
  const props = Object.assign({}, el.dataset);

  ReactDOM.render(<App {...props} />, el);
}

document
  .querySelectorAll('.__react-root')
  .forEach(renderAppInElement)

<div>Some Article</div>
<div id="CommentBox" data-post_id="10" class="__react-root"></div>

<script src="/all.js"></script>

редактировать

поскольку webpack отлично поддерживает разделение кода и LazyLoading, я подумал, что имеет смысл включить пример, когда вам не нужно загружать все ваши приложения в один пакет, но разделить их и загружать по требованию.

import React from 'react';
import ReactDOM from 'react-dom';

const apps = {
  'One': () => import('./One'),
  'Two': () => import('./Two'),
}

const renderAppInElement = (el) => {
  if (apps[el.id])  {
    apps[el.id]().then((App) => {
      ReactDOM.render(<App {...el.dataset} />, el);
    });
  }
}

вы можете указать несколько точек входа для приложения в webpack.конфиг.файл js:

var config = {
  entry: {
    home: path.resolve(__dirname, './src/main'),
    page1: path.resolve(__dirname, './src/page1'),
    page2: path.resolve(__dirname, './src/page2'),
    vendors: ['react']
  },
 output: {
    path: path.join(__dirname, 'js'),
    filename: '[name].bundle.js',
    chunkFilename: '[id].chunk.js'
  },
}

тогда вы можете иметь в своей папке src три разных html-файла с соответствующими файлами js (пример для page1):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Page 1</title>
</head>
<body>
  <div id="app"></div>
  <script src="./vendors.js"></script>
  <script src="./page1.bundle.js"></script>
</body>
</html>

JavaScript-файл:

import React from 'react'
import ReactDom from 'react-dom'
import App from './components/App'
import ComponentA from './components/ReactComponentA'
ReactDom.render(<div>
                  <App title='page1' />
                  <ReactComponentA/>
                 </div>, document.getElementById('app'))

различные компоненты React могут быть загружены для каждой отдельной страницы.


Edit: 11/01/2015

Я построение приложения с нуля и учусь, как я иду, но я думаю, что вы ищете React-Маршрутизатор. React-маршрутизатор сопоставляет компоненты с определенными URL-адресами. Например:

render((
    <Router>
        <Route path="/" component={App}>
            <Route path="api/animals" component={Animals}>
               <Route path="birds" component={Birds}/>
               <Route path="cats" component={Cats}/>
            </Route>
        </Route>
        <Route path="api/search:term" component={AnimalSearchBox}>
    </Router>
), document.body)

в случае поиска "term" доступен как свойство в AnimalSearchBox:

componentDidMount() {
    // from the path `/api/search/:term`
    const term = this.props.params.term
}

попробуйте. этой учебник-это тот, который поставил меня над вершиной с точки зрения моего понимания это и другие связанные темы.

оригинальный ответ следующее:

Я нашел свой путь сюда, ища тот же ответ. Смотрите, если этой пост вдохновляет вас. Если ваше приложение похоже на мое, оно будет иметь области, которые меняются очень мало и варьируются только в основном корпусе. Вы можете создать виджет, в обязанности которого входит визуализация другого виджета в зависимости от состояния приложения. Используя архитектуру flux, вы можете отправить навигацию действие, которое изменяет состояние вашего виджета тела, эффективно обновляя только тело страницы.

это подход, который я пытаюсь сейчас.


вы используете CMS? Им, как правило, нравится изменять URL-адреса, которые могут нарушить ваше приложение.

другой способ-использовать что-то вроде Реагировать Среды Обитания.

С его помощью вы можете регистрировать компоненты, и они автоматически подвергаются воздействию dom.

пример

зарегистрировать компонент(ы):

container.register('AnimalBox', AnimalBox);
container.register('AnimalSearchBox', AnimalSearchBox);

тогда они доступны в вашем dom, как это:

<div data-component="AnimalBox"></div>

<div data-component="AnimalSearchBox"></div>

выше будет автоматически заменен вашими компонентами react.

вы также можете автоматически передавать свойства (или реквизит) своим компонентам:

<div data-component="AnimalBox" data-prop-size="small"></div>

это разоблачит size в качестве опоры для вашего компонента. Есть дополнительные опции для передачи других типов, таких как json, array, ints, floats и т. д.