我一直在玩React,到目前为止我非常喜欢它。我正在使用NodeJS构建一个应用程序,并希望将React用于整个应用程序中的一些交互式组件。我不想让它成为单页应用程序。
我还没有在网上找到任何可以回答以下问题的内容:
如何在多页应用中分解或捆绑我的React组件?
目前我的所有组件都在一个文件中,即使我可能永远不会在应用程序的某些部分加载它们。
到目前为止,我正在尝试使用条件语句通过搜索React将呈现的容器的ID来呈现组件。我不是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 :(得分:71)
目前,我正在做类似的事情。
应用程序不是一个完整的React应用程序,我使用React进行动态Stuff,比如CommentBox,它是autark。并且可以包含在具有特殊参数的任何点...
但是,我的所有子应用都已加载并包含在单个文件all.js
中,因此浏览器可以跨页面缓存它。
当我需要在SSR模板中包含一个应用程序时,我只需要在类&#34; __ react-root&#34;中包含一个DIV。和一个特殊的ID,(要呈现的React App的名称)
逻辑非常简单:
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完全支持代码分割&amp; 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);
});
}
}
答案 1 :(得分:44)
您可以在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文件(例如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组件。
答案 2 :(得分:32)
编辑:2015年11月1日
我正在从头开始构建一个应用程序,我正在学习,但我认为你所寻找的是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)
在搜索案例中,'term'可以作为AnimalSearchBox中的属性访问:
componentDidMount() {
// from the path `/api/search/:term`
const term = this.props.params.term
}
试一试。 This教程可以帮助我理解这个和其他相关主题。
原始答案如下:
我在这里寻找同样的答案。看看this帖子是否会激励你。如果您的应用程序与我的应用程序类似,那么它的区域变化很小,仅在主体中有所不同。您可以创建一个小部件,它负责根据应用程序的状态呈现不同的小部件。使用磁通体系结构,您可以调度导航操作,更改您的主体窗口小部件切换的状态,从而有效地更新页面主体。
这就是我现在正在尝试的方法。
答案 3 :(得分:11)
您使用的是CMS吗?他们倾向于喜欢更改可能会破坏您申请的网址。
另一种方法是使用像React Habitat这样的东西。
有了它,你可以注册组件,它们会自动暴露给dom。
实施例
注册组件:
container.register('AnimalBox', AnimalBox);
container.register('AnimalSearchBox', AnimalSearchBox);
然后他们可以在你的dom中使用它们:
<div data-component="AnimalBox"></div>
<div data-component="AnimalSearchBox"></div>
以上内容将自动替换为您的反应组件。
然后,您也可以自动将属性(或道具)传递给组件:
<div data-component="AnimalBox" data-prop-size="small"></div>
这会将size
公开为您的组件的道具。有additional options用于传递其他类型,如json,array,int,float等。
答案 4 :(得分:1)
我知道距问这个问题已经有一段时间了,但希望这对某人有帮助。
如@Cocomico所述,您可以在webpack.config.js文件中为应用程序提供几个入口点。如果您正在寻找一个简单的Webpack设置(基于多个入口点的思想),该设置允许您将React组件添加到静态页面,则可以考虑使用以下方法:https://github.com/przemek-nowicki/multi-page-app-with-react
答案 5 :(得分:-1)
我建议您看看InertiaJS:https://inertiajs.com/
使用Inertia,您可以像选择服务器端Web框架一样来构建应用程序。您可以将框架的现有功能用于路由,控制器,中间件,身份验证,授权,数据提取等。
唯一不同的是您的视图层。视图不是JavaScript服务器渲染(例如Blade或ERB模板),而是JavaScript页面组件。这使您可以使用React,Vue或Svelte构建整个前端。