一、BrowserRouter 与 HashRouter
1、基本介绍
(1)BrowserRouter
-
URL 形式:
example.com/path -
使用 HTML5 的 History API(pushState、replaceState)
-
需要服务器配置,所有路径都返回
index.html,否则刷新会 404
(2)HashRouter
-
URL 形式:
example.com/#/path -
使用 URL 的 hash(
#)部分 -
无需服务器配置,hash 变化不会向服务器发请求
2、基本使用
- 使用 BrowserRouter
js
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";
// 渲染 App 组件到页面
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root"),
);
- 使用 HashRouter
js
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { HashRouter } from "react-router-dom";
// 渲染 App 组件到页面
ReactDOM.render(
<HashRouter>
<App />
</HashRouter>,
document.getElementById("root"),
);
二、push 模式与 replace 模式
1、基本介绍
-
push 模式(默认):在历史栈中添加新记录,可以点击浏览器后退按钮返回上一页
-
replace 模式:替换当前历史记录,不添加新记录,点击后退不会回到当前页,直接跳到更早的页面
2、replace 模式演示
(1)page
- About 组件
js
import React, { Component } from "react";
export default class About extends Component {
render() {
return <h3>About Content</h3>;
}
}
- Home 组件
js
import React, { Component } from "react";
export default class Home extends Component {
render() {
return <h3>Home Content</h3>;
}
}
(2)main
- App 组件
js
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";
export default class App extends Component {
render() {
return (
<div>
<h2>React Router Demo</h2>
<div>
<Link replace to="/about">About</Link>
<Link replace to="/home">Home</Link>
</div>
<div>
<Route path="/about" component={About} />
<Route path="/home" component={Home} />
</div>
</div>
);
}
}
- index.js
js
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";
// 渲染 App 组件到页面
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root"),
);
三、编程式导航
1、page
- Message 组件
js
import React, { Component } from "react";
import { Link, Route } from "react-router-dom";
import Detail from "./Detail";
import News from "./News";
import Tip from "./Tip";
export default class Message extends Component {
state = {
messageArr: [
{ id: "01", title: "消息 1" },
{ id: "02", title: "消息 2" },
{ id: "03", title: "消息 3" },
],
};
pushParamsShow = (id, title) => {
this.props.history.push(`/message/detail/${id}/${title}`);
};
replaceParamsShow = (id, title) => {
this.props.history.replace(`/message/detail/${id}/${title}`);
};
pushSearchShow = (id, title) => {
this.props.history.push(`/message/news/?id=${id}&title=${title}`);
};
replaceSearchShow = (id, title) => {
this.props.history.replace(`/message/news/?id=${id}&title=${title}`);
};
pushStateShow = (id, title) => {
this.props.history.push({ pathname: "/message/tip", state: { id, title } });
};
replaceStateShow = (id, title) => {
this.props.history.replace({ pathname: "/message/tip", state: { id, title } });
};
back = () => {
this.props.history.goBack();
};
forward = () => {
this.props.history.goForward();
};
go = () => {
this.props.history.go(2);
};
render() {
const { messageArr } = this.state;
return (
<div>
<h3>传递 params 参数</h3>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
<button onClick={() => this.pushParamsShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
<button onClick={() => this.replaceParamsShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
</li>
);
})}
</ul>
<Route path="/message/detail/:id/:title" component={Detail} />
<h3>传递 search 参数</h3>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
<button onClick={() => this.pushSearchShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
<button onClick={() => this.replaceSearchShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
</li>
);
})}
</ul>
<Route path="/message/news" component={News} />
<h3>传递 state 参数</h3>
<ul>
{messageArr.map((msgObj) => {
return (
<li key={msgObj.id}>
<button onClick={() => this.pushStateShow(msgObj.id, msgObj.title)}>{msgObj.title}(push)</button>
<button onClick={() => this.replaceStateShow(msgObj.id, msgObj.title)}>{msgObj.title}(replace)</button>
</li>
);
})}
</ul>
<Route path="/message/tip" component={Tip} />
<button onClick={this.back}>回退</button>
<button onClick={this.forward}>前进</button>
<button onClick={this.go}>go</button>
</div>
);
}
}
- Detail 组件
js
import React, { Component } from "react";
export default class Detail extends Component {
render() {
const { id, title } = this.props.match.params;
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
}
- News 组件
js
import React, { Component } from "react";
import qs from "qs";
export default class News extends Component {
render() {
const { search } = this.props.location;
const { id, title } = qs.parse(search.slice(1));
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
}
- Tip 组件
js
import React, { Component } from "react";
export default class Tip extends Component {
render() {
const { id, title } = this.props.location.state || {};
return (
<ul>
<li>id: {id}</li>
<li>title: {title}</li>
</ul>
);
}
}
2、main
- App 组件
js
import React, { Component } from "react";
import { Route } from "react-router-dom";
import Message from "./pages/Message";
export default class App extends Component {
render() {
return (
<div>
<Route path="/message" component={Message} />
</div>
);
}
}
- index.js
js
import React from "react"; // 引入 React 核心库
import ReactDOM from "react-dom"; // 引入 ReactDOM
import App from "./App"; // 引入 App 组件
import { BrowserRouter } from "react-router-dom";
// 渲染 App 组件到页面
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root"),
);
四、withRouter
1、基本介绍
-
withRouter 的主要作用是让那些不是通过路由直接渲染的组件,也能访问到路由相关的属性,如 history、location 和 match
-
在 React Router 中,只有直接被 Route 渲染的组件,其 props 里会自动获得路由信息
2、演示
- Header 组件
js
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
class Header extends Component {
back = () => {
this.props.history.goBack();
};
forward = () => {
this.props.history.goForward();
};
go = () => {
this.props.history.go(-2);
};
render() {
console.log("Header 组件收到的 props 是", this.props);
return (
<div className="page-header">
<h2>React Router Demo</h2>
<button onClick={this.back}>回退</button>
<button onClick={this.forward}>前进</button>
<button onClick={this.go}>go</button>
</div>
);
}
}
export default withRouter(Header);