如何使用 React 创建多页应用程序
Posted
技术标签:
【中文标题】如何使用 React 创建多页应用程序【英文标题】:How to create multiple page app using react 【发布时间】:2017-06-16 19:46:19 【问题描述】:我使用 react js 创建了一个单页网络应用程序。我使用webpack
创建了所有组件的捆绑包。但现在我想创建许多其他页面。大多数页面都与 API 调用相关。即在index.html
中,我显示了来自API
的内容。我想在另一个页面中插入内容来解析来自 API 的数据。 Webpack 将所有 react 压缩到一个文件 bundle.js
中。但是webpack
的配置如下:
const webpack = require('webpack');
var config =
entry: './main.js',
output:
path:'./',
filename: 'dist/bundle.js',
,
devServer:
inline: true,
port: 3000
,
module:
loaders: [
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query:
presets: ['es2015', 'react']
]
,
plugins: [
new webpack.DefinePlugin(
'process.env':
'NODE_ENV': JSON.stringify('production')
),
new webpack.optimize.UglifyJsPlugin(
compress:
warnings: false
)
]
module.exports = config;
现在,我很困惑webpack
的配置将用于其他页面,或者使用react.js
构建多页面应用程序的正确方法是什么
【问题讨论】:
您可以为应用程序中的每个页面创建多个输出文件。 让我在这里包含一些上下文,默认情况下npm run build
创建一个静态 index.html,静态性质对于制作静态只读托管网站很重要,现在通常网站都有一个 about 页面, page1, page2 等,它们可能是非常大的文本/图像页面,单个 index.html 中的整个包会损害加载时间和网站在慢速连接或设备上的响应能力,所以我们如何将输出页面拆分为单独的有助于提高响应能力的页面
【参考方案1】:
(确保使用 npm 安装 react-router!)
要使用 react-router,请执行以下操作:
创建一个文件,其中包含使用 Route、IndexRoute 组件定义的路由
注入 Router(带有 'r'!)组件作为应用的***组件,传递路由文件中定义的路由和历史类型(hashHistory,浏览器历史)
添加 this.props.children 以确保在那里呈现新页面 使用 Link 组件更改页面第 1 步 routes.js
import React from 'react';
import Route, IndexRoute from 'react-router';
/**
* Import all page components here
*/
import App from './components/App';
import MainPage from './components/MainPage';
import SomePage from './components/SomePage';
import SomeOtherPage from './components/SomeOtherPage';
/**
* All routes go here.
* Don't forget to import the components above after adding new route.
*/
export default (
<Route path="/" component=App>
<IndexRoute component=MainPage />
<Route path="/some/where" component=SomePage />
<Route path="/some/otherpage" component=SomeOtherPage />
</Route>
);
第 2 步 入口点(进行 DOM 注入的地方)
// You can choose your kind of history here (e.g. browserHistory)
import Router, hashHistory as history from 'react-router';
// Your routes.js file
import routes from './routes';
ReactDOM.render(
<Router routes=routes history=history />,
document.getElementById('your-app')
);
第 3 步 App 组件 (props.children)
在您的 App 组件的渲染中,添加 this.props.children:
render()
return (
<div>
<header>
This is my website!
</header>
<main>
this.props.children
</main>
<footer>
Your copyright message
</footer>
</div>
);
第 4 步 使用链接导航
在你的组件渲染函数返回 JSX 值的任何地方,使用 Link 组件:
import Link from 'react-router';
(...)
<Link to="/some/where">Click me</Link>
【讨论】:
我对这里的初学者感到困惑。单页应用程序不是 react-router 吗?我的意思是,如果你有一个 index.html 文件,那么只有它会是一个页面吗?其他人会像在单页应用程序中一样被注入,对吗? 这不是 webpack 中的多页应用。如果您有超过 1 个条目,那么您就有了多页应用程序 (webpack.js.org/concepts/entry-points/#multi-page-application) 如何在这些不同的页面组件之间共享状态? @robinmetral 使用类似 Redux 的东西。或者你可以让一个父组件保存数据,然后将它传递给它下面的多个路由(这是一个称为“容器”组件的概念)。Attempted import error: 'hashHistory' is not exported from 'react-router' (imported as 'history').
【参考方案2】:
前言
此答案使用react-router
v4+ 中包含的dynamic routing 方法。 Other answers 可能会引用以前使用的“静态路由”方法,即 abandoned 由 react-router
提供。
解决方案
react-router
是一个很好的解决方案。您将页面创建为组件,路由器根据当前 URL 交换页面。换句话说,它会用新页面动态替换原始页面,而不是向服务器请求新页面。
对于网络应用,我建议您先阅读以下两点:
Full Tutorial react-router docs;它将帮助您更好地了解路由器的工作原理。一般做法总结:
1 - 将react-router-dom
添加到您的项目中:
纱线
yarn add react-router-dom
或NPM
npm install react-router-dom
2 - 将您的 index.js
文件更新为:
import BrowserRouter from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<App /> /* The various pages will be displayed by the `Main` component. */
</BrowserRouter>
), document.getElementById('root')
);
3 - 创建一个Main
组件,它将根据当前 URL 显示您的页面:
import React from 'react';
import Switch, Route from 'react-router-dom';
import Home from '../pages/Home';
import Signup from '../pages/Signup';
const Main = () =>
return (
<Switch> /* The Switch decides which component to show based on the current URL.*/
<Route exact path='/' component=Home></Route>
<Route exact path='/signup' component=Signup></Route>
</Switch>
);
export default Main;
4 - 在App.js
文件中添加Main
组件:
function App()
return (
<div className="App">
<Navbar />
<Main />
</div>
);
5 - 将Link
s 添加到您的页面。
(您必须使用 react-router-dom
中的 Link
而不是普通的旧 <a>
才能使路由器正常工作。)
import Link from "react-router-dom";
...
<Link to="/signup">
<button variant="outlined">
Sign up
</button>
</Link>
【讨论】:
不过效果很好,在第 1 节中添加一行。 1 例如import ReactDOM from 'react-dom' 加上使用 useHistory 以编程方式从一个屏幕移动到另一个屏幕。【参考方案3】:这是一个广泛的问题,您可以通过多种方式实现这一目标。根据我的经验,我见过很多单页应用程序都有一个入口点文件,例如index.js
。该文件将负责“引导”应用程序,并将成为 webpack 的入口点。
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Application from './components/Application';
const root = document.getElementById('someElementIdHere');
ReactDOM.render(
<Application />,
root,
);
您的<Application />
组件将包含您的应用程序的下一部分。你已经说过你想要不同的页面,这让我相信你正在使用某种路由。这可以与需要在应用程序启动时调用的任何库一起包含在此组件中。 react-router
, redux
, redux-saga
, react-devtools
浮现在脑海中。这样,你只需要在你的 webpack 配置中添加一个入口点,从某种意义上说,一切都会慢慢下降。
设置路由器后,您可以选择将组件设置为特定匹配的路由。如果你有一个/about
的 URL,你应该在你正在使用的任何路由包中创建路由,并使用你需要的任何信息创建一个 About.js
的组件。
【讨论】:
【参考方案4】:你的问题的第二部分得到了很好的回答。这是第一部分的答案:如何使用webpack输出多个文件:
entry:
outputone: './source/fileone.jsx',
outputtwo: './source/filetwo.jsx'
,
output:
path: path.resolve(__dirname, './wwwroot/js/dist'),
filename: '[name].js'
,
这将在目标文件夹中生成 2 个文件:outputone.js 和 outputtwo.js。
【讨论】:
【参考方案5】:根据@lucas-andrade 的上述答案:对于react-router
版本>= 6,Switch
不再存在(请参阅https://github.com/remix-run/react-router/issues/8439)。第3步的内容变成:
import React from 'react';
import Routes, Route from 'react-router-dom';
import Home from '../pages/Home';
import Signup from '../pages/Signup';
const Main = () =>
return (
<Routes>
<Route path='/' element=Home></Route>
<Route path='/signup' element=Signup></Route>
</Routes>
);
export default Main;
【讨论】:
【参考方案6】:也可以使用gatsby 一个专门用于静态多页应用程序的反应框架。
【讨论】:
以上是关于如何使用 React 创建多页应用程序的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 vue-cli(webpack) 创建多页应用程序(每个应用程序使用不同的路由器,以及不同的 dist/index.html)