BrowserRouter和HashRouter路由模式

  • BrowserRouter
    • 如果前端使用了browserRouter,每次改变路由时,会向服务器发送请求,因为服务器未配置对应的路径指向对应的文件,自然导致出现404的情况.(对于初始化页面,即路由为/时,不会发送请求)
  • HashRouter
    • 由于hashRouter会在路径上添加#分隔路径,而#后面的所有请求都不会发送到服务器端,即对于服务器而言,路径依旧是localhost:3000,路由切换在前端完成。

如果做服务端渲染的话建议使用BrowserRouter, 在开发阶段可以在webpack devServer中配置historyApiFallback: true,或者在使用BrowserRouter需要再加一层服务器配置(node/nginx),让前端发送的请求映射到对应的html文件上。不然还是建议用HashRouter。

HashRouter路由

  • 新建两个js文件,分别命名为“home”和“other”

home.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import React from 'react';

export default class Home extends React.Component {

constructor(props){
super(props);
}

render() {
return (
<div>
{/* 地址栏跳转 */}
{/* <a href='#/other/1'>跳转到other页面</a> */}

<button onClick={ ()=>{
this.props.history.push({
pathname : '/other',
state :{
id:3
}
});

//在可能会出现死循环的地方使用replace来跳转
// this.props.history.replace('/other');
// this.props.history.replace({
// pathname:'/other',
// state : {
// id:4
// }
// });

//返回上级页面
// this.props.history.goBack();
}
}> 使用函数跳转到other页面 </button>
</div>
)
}
}

other.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import React from 'react';

export default class Other extends React.Component {

constructor(props){
super(props);
}

componentDidMount(){
//地址栏跳转传参
// console.log(this.props.match.params);

//函数跳转传参
console.log(this.props.history.location.state);
}

render() {
return (
<div>
<a href='#/'>回到home页面</a>
</div>
)
}
}
  • 新建一个HashRouter路由组件

    Router.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import React from 'react';
import {HashRouter, Route, Switch} from 'react-router-dom';
import Home from './home';
import Other from './other';

const BasicRoute = () => (
<HashRouter>
<Switch>
<Route exact path="/" component={Home}/>
<Route exact path="/other" component={Other}/>
{/* 地址栏跳转传参 */}
{/* <Route exact path="/other/:id" component={Other}/> */}
</Switch>
</HashRouter>
);

export default BasicRoute;

以上定义了一个HashRouter路由组件,将两个页面组件Home和Other使用Route组件包裹,外面套用Switch作路由匹配,当路由组件检测到地址栏与Route的path匹配时,就会自动加载响应的页面。

  • 在入口文件index.js中配置
1
2
3
4
5
6
7
8
9
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Router from './Router';

ReactDOM.render(
<Router />,
document.getElementById('root')
);
页面跳转:
  • a标签跳转:<a href='#/'>回到home</a>

  • 函数跳转:

    • this.props.history.push('/other');
    • this.props.history.replace('/other');//避免重复使用push或a标签跳转产生死循环时使用
    • this.props.history.goBack('/other');//返回上级页面
跳转传参:
  • url传参
    • 路由组件配置<Route exact path="/other/:id" component={Other}/>跳转时配置<a href='#/other/1'>跳转到other页面</a>,react-router-dom就是通过/:去匹配url传递的参数
  • 函数隐式传参
    • 向跳转函数添加参数(以push()函数为例)
      1
      2
      3
      4
      5
      6
      7
       	//push()与replace()、goBack()同理
      this.props.history.push({
      pathname : '/other',
      state :{
      id:3
      }
      });
      查看参数集:
      • url传参方式:this.props.match.params
    • 函数隐式传参方式:this.props.history.location.state

BrowserRouter路由

  • 修改Router.js文件,成为一个BrowserRouter路由组件

    Router.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import React from 'react';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Home from './home';
import Other from './other';

const BasicRoute = () => (
<HashRouter>
<BrowserRouter>
<Route exact path="/" component={Home}/>
<Route path="/other" name="other" component={Other}/>
</BrowserRouter>
</HashRouter>
);

export default BasicRoute;
页面跳转:
  • a标签跳转:<Link exact to="/other">点击跳转</Link>注意: 引入import {Link} from 'react-router-dom';

  • 函数跳转:与HashRouter路由方式相同

跳转传参:
  • url传参

    • HTML方式:<Link to={ pathname : ' /user' , state : { day: 'Friday' }}>点击跳转</Link> 注意: 引入import {Link} from 'react-router-dom';
  • 函数隐式传参

    • 向跳转函数添加参数与HashRouter路由方式相同

    查看参数集:

    • 函数隐式传参方式:与HashRouter路由方式相同