如何使用 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 -Links 添加到您的页面。

(您必须使用 react-router-dom 中的 Link 而不是普通的旧 &lt;a&gt; 才能使路由器正常工作。)

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,
);

您的&lt;Application /&gt; 组件将包含您的应用程序的下一部分。你已经说过你想要不同的页面,这让我相信你正在使用某种路由。这可以与需要在应用程序启动时调用的任何库一起包含在此组件中。 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 创建多页应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Meteor 创建多页应用程序?

如何使用 vue-cli(webpack) 创建多页应用程序(每个应用程序使用不同的路由器,以及不同的 dist/index.html)

AngularJS:多页网站

react-router-dom 中的多页路由问题

如何在stimulsoft中为多页报告创建目录?

多页Excel转换成PDF时如何保存为单独文件