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

61

Я играю с 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')
    );
}

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

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

  • 0
    попробуйте использовать плагин requirejs.
  • 2
    Если вы не возражаете, что ReactJs - это очень большая библиотека JS, которую нужно инициализировать для каждой страницы (как вы сказали, вы не создаете одностраничное приложение), то я не уверен, что это важно Мы объединили все компоненты в один файл. Это будет кэшировано на клиенте. Когда страница загружается, пусть она render правильный компонент в блоке script .
Показать ещё 1 комментарий

4 ответа

40
Лучший ответ

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

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

Однако все мои вспомогательные приложения загружаются и включаются в один файл 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>

Как вы думаете?

  • 1
    Выглядит отлично, кто-нибудь запустил это при использовании npm create-Reaction-app? Я не думаю, что это будет работать для меня ... У меня сейчас работает приложение 1, и я вижу, как оно может работать, но моя сборка не создаст рабочую сборку, которая работает правильно.
  • 0
    @Sprose должен работать и с create-реагировать на приложение, я что-то упустил? Может быть, вы можете поделиться небольшим примером на GitHub, где это не так, я не вижу причины, почему это не должно
Показать ещё 6 комментариев
25

Изменить: 11/01/2015

Я создаю приложение с нуля и изучаю, когда я иду, но я думаю, что вы ищете React-Router. React-Router сопоставляет ваши компоненты с определенными 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)

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

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

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

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

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

То, что я сейчас пытаюсь сделать.

  • 0
    Это полный ответ?
  • 8
    Что делать, если путь URL создается моим внутренним кодом (в данном случае nodejs)? Будет ли Router работать так же, как в одностраничном приложении?
Показать ещё 2 комментария
9

Вы можете указать несколько точек входа для приложения в файле webpack.config.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 файлами (пример для страницы 1):

<!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 могут быть загружены для каждой отдельной страницы.

  • 0
    Ваш ответ лучше всего подходит для его проекта.
  • 0
    Я читал об этом ниже на странице webex. webpack version < 4 it was common to add vendors as separate entrypoint to compile it as separate file (in combination with the CommonsChunkPlugin). This is discouraged in webpack 4. Instead the optimization.splitChunks option takes care of separating vendors and app modules and creating a separate file. Do not create a entry for vendors or other stuff which is not the starting point of execution. Итак, следует ли обновить этот образец для веб-пакета 4+?
6

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

Другой способ - использовать React Habitat.

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

Пример

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

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

Затем они доступны в вашем доме следующим образом:

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

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

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

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

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

Это откроет size как опору для вашего компонента. Существуют дополнительные параметры для передачи других типов, таких как json, array, ints, float и т.д.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню