Использование 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 и т. д.