Я играю с 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')
);
}
Я все еще читаю документацию и еще не нашел того, что мне нужно для многостраничного приложения.
Спасибо заранее.
Ответ 1
В настоящее время я занимаюсь чем-то похожим.
Приложение не является полноценным приложением React, я использую React для динамических вещей, таких как 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>
Edit
Так как веб-пакет прекрасно поддерживает разделение кода & 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);
});
}
}
Ответ 2
Вы можете указать несколько точек входа для приложения в файле 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 могут быть загружены для каждой отдельной страницы.
Ответ 3
Я создаю приложение с нуля и учусь по ходу дела, но я думаю, что вы ищете 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
}
Попробуйте. Это руководство - то, что ставит меня выше всего с точки зрения моего понимания этой и других смежных тем.
Исходный ответ:
Я нашел свой путь здесь в поисках того же ответа. Посмотрите, этот пост вдохновляет вас. Если ваше приложение чем-то похоже на мое, оно будет иметь области, которые очень мало меняются и изменяются только в основной части. Вы можете создать виджет, в обязанности которого входит рендеринг другого виджета в зависимости от состояния приложения. Используя потоковую архитектуру, вы могли бы отправлять действие навигации, которое изменяет состояние, в которое включается ваш виджет тела, эффективно обновляя только тело страницы.
Это подход, который я пытаюсь сейчас.
Ответ 4
Используете ли вы 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 и т.д.
Ответ 5
Я знаю, что прошло много времени с тех пор, как был задан этот вопрос, но, надеюсь, это кому-нибудь поможет.
Как упомянул @Cocomico, вы можете указать несколько точек входа для приложения в файле webpack.config.js. Если вы ищете простую настройку Webpack (основанную на идее множественных точек входа), которая позволяет добавлять компоненты React на статические страницы, вы можете рассмотреть возможность использования этого: https://github.com/przemek-nowicki/multi-page-app-with-react