Использование 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. И может быть включен в любой момент с помощью специальных параметров..
тем не менее, все мои суб приложения загружаются и включаются в один файл
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
поскольку 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 file:
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 могут быть загружены для каждой отдельной страницы.
Edit: 11/01/2015
Я построение приложения с нуля и учусь, как я иду, но я думаю, что вы ищете React-Router. Реагировать-маршрутизатор сопоставляет компоненты к определенным адресам. Например:
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 }попробовать его. этой учебник-это тот, который поставил меня на вершину с точки зрения моего понимания эту и другие смежные темы.
оригинальный ответ следующее:
Я нашел свой путь сюда, ища тот же ответ. Смотрите, если этой пост вдохновляет вас. Если ваше приложение похоже на мое, у него будут области, которые меняются очень мало и меняются только в основном корпусе. Вы можете создать виджет, в обязанности которого входит оказывать другой виджет на основе состояния приложения. Используя архитектуру потока, вы можете отправить навигацию действие, изменяющее состояние, на которое переключается виджет тело, эффективно обновляя только тело страницы.
это подход, который я пытаюсь сейчас.
вы используете CMS? Они, как правило, любят изменять URL-адреса, которые могут нарушить ваше приложение.
другой способ использует что-то вроде Реагировать Среда Обитания.
С его помощью вы можете регистрировать компоненты, и они автоматически подвергаются воздействию 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, массивы, ints, поплавки и т. д.
Comments