React-Router
参考学习地址: https://reactrouter.com/web/guides/quick-start
// 5 的版本主要是针对 react Hook 做更好的支持
-
安装
npm install react-router-dom --save -
路由的作用
单页面应用(SPA),路由跳转,切换显示视图
HashRouter与BrowserRouter区别
BrowserRouter:
原理是H5的history API,IE9及以下不兼容,需要由web server支持,在web client这边window.location.pathname被react router解析,http://localhost:3000/home
HashRouter:
原理是URL的hash,不需要由web server支持,因为它的只有‘/’path需要由web server支持,而#/react/route URL不能被web server读取,在web client这边window,location.hash被react router解析,http://localhost:3000/home#/home
Home.jsx
import React from 'react';
export default class Home extends React.Component {
render() {
return <div>Home</div>;
}
}
Mine.jsx
import React from 'react';
export default class Mine extends React.Component {
render() {
return <div>Mine</div>;
}
}
App.jsx
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route } from 'react-router-dom';
/**
* HashRouter: 锚点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
function App() {
return (
<div className="App">
<Router>
<Route path="/home" component={Home}></Route>
<Route path="/mine" component={Mine}></Route>
</Router>
</div>
);
}
export default App;
Link跳转
react-router里的Link标签 和 a 标签有什么区别??
从最终渲染的Dom来看,两者都是链接,都是标签,区别是:
Link标签: 是react-router里实现路由跳转的链接,一般配合使用,react-router 接管了其默认的链接跳转行为,区别去传统的页面跳转,的”跳转”行为只会触发相匹配的对应的页面内容更新,而不会刷新整个页面。 做了三件事情: 1.有onclick那就执行onclick 2.click的时候阻止a标签默认事件 3.根据跳转href(即是to ),用history(web前端路由两种方式之一,history & hash)跳转,此时只是链接变了,并没有刷新页面
a 标签: 是普通的超链接了,用于从当前页面跳转到href指向的另一个页面(非锚点情况)。
index.jsx
import React from 'react';
import { Link } from 'react-router-dom';
export default class Nav extends React.Component {
render() {
return (
<div>
<ul>
<li>
<Link to="/home">Home页面(Link)</Link>
</li>
<li>
<Link to="/mine">Mine页面(Link)</Link>
</li>
<li>
<a href="#/home">Home页面(a)</a>
</li>
<li>
<a href="#/mine">Mine页面(a)</a>
</li>
</ul>
</div>
);
}
}
App.jsx
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route } from 'react-router-dom';
import Nav from './components/Nav';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Route path="/home" component={Home}></Route>
<Route path="/mine" component={Mine}></Route>
</Router>
</div>
);
}
export default App;
exact匹配规则和strict精准匹配
exact属性为true时路径中的hash值必须和path完全一致才渲染对应的组件,如果为false则'/'也可以匹配'/xxx';(如果strict属性为false,则末尾是否包含反斜杠结尾不影响匹配结果)
strict属性主要就是匹配反斜杠,规定是否匹配末尾包含反斜杠的路径,如果exact,strict为true,则path中不包含反斜杠结尾。(注意:这个要跟exact配合使用)
总结:如果没有子路由的情况,建议大家配都加一个exact;如果有子路由,建议在子路由中加exact,父路由不加。
添加pages/UCenter.jsx
import React from 'react';
const UCenter = () => {
return <div>Hello UCenter</div>;
};
export default UCenter;
在components/Nav/index.jsx中引入Link
import React from 'react';
import { Link } from 'react-router-dom';
export default class Nav extends React.Component {
render() {
return (
<div>
<ul>
<li>
<Link to="/">Home页面(Link)</Link>
</li>
<li>
<Link to="/mine">Mine页面(Link)</Link>
</li>
<li>
<Link to="/mine/ucenter">UCenter页面(Link)</Link>
</li>
<li>
<a href="#/home">Home页面(a)</a>
</li>
<li>
<a href="#/mine">Mine页面(a)</a>
</li>
</ul>
</div>
);
}
}
App.js中引入UCenter组件
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route } from 'react-router-dom';
import Nav from './components/Nav';
import UCenter from './pages/UCenter';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
/**
* /mine/ucenter 包含了 /mine
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Route exact path="/" component={Home}></Route>
<Route
strict
exact={true}
path="/mine"
component={Mine}
></Route>
<Route
strict
exact
path="/mine/ucenter"
component={UCenter}
></Route>
</Router>
</div>
);
}
export default App;
404页面和Switch
有
无
添加404页面组件:/pages/NotFound.jsx
import React from 'react';
const NotFound = () => {
return <div>404页面</div>;
};
export default NotFound;
App.js中引入NotFound组件
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import Nav from './components/Nav';
import UCenter from './pages/UCenter';
import NotFound from './pages/NotFound';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
/**
* /mine/ucenter 包含了 /mine
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Switch>
<Route exact path="/" component={Home}></Route>
<Route
strict
exact={true}
path="/mine"
component={Mine}
></Route>
<Route
strict
exact
path="/mine/ucenter"
component={UCenter}
></Route>
<Route component={NotFound}></Route>
</Switch>
</Router>
</div>
);
}
export default App;
render func
新建一个组件pages/Demo.jsx
import React from 'react';
const Demo = (props) => {
console.log(props);
return <div>Demo: {props.name}</div>;
};
export default Demo;
App.js
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import Nav from './components/Nav';
import UCenter from './pages/UCenter';
import NotFound from './pages/NotFound';
import Demo from './pages/Demo';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
/**
* /mine/ucenter 包含了 /mine
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Switch>
<Route exact path="/" component={Home}></Route>
<Route
strict
exact={true}
path="/mine"
component={Mine}
></Route>
<Route
strict
exact
path="/mine/ucenter"
component={UCenter}
></Route>
{/* <Route
path="/demo"
render={() => <div>Hello Demo</div>}
></Route> */}
<Route
path="/demo"
render={(props) => <Demo {...props} name="你好" />}
></Route>
<Route component={NotFound}></Route>
</Switch>
</Router>
</div>
);
}
export default App;
NavLink高亮
components/Nav/index.jsx
import React from 'react';
import { NavLink } from 'react-router-dom';
import './style.css';
export default class Nav extends React.Component {
render() {
return (
<div>
<ul>
<li>
<NavLink
activeClassName="selected"
activeStyle={{ color: 'green' }}
exact
to="/"
>
Home页面(Link)
</NavLink>
</li>
<li>
<NavLink activeClassName="selected" exact to="/mine">
Mine页面(Link)
</NavLink>
</li>
<li>
<NavLink
activeClassName="selected"
exact
to="/mine/ucenter"
>
UCenter页面(Link)
</NavLink>
</li>
<li>
<a href="#/home">Home页面(a)</a>
</li>
<li>
<a href="#/mine">Mine页面(a)</a>
</li>
</ul>
</div>
);
}
}
components/Nav/style.css
.selected{
color: red;
}
App.js
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import Nav from './components/Nav';
import UCenter from './pages/UCenter';
import NotFound from './pages/NotFound';
import Demo from './pages/Demo';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
/**
* /mine/ucenter 包含了 /mine
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Switch>
<Route exact path="/" component={Home}></Route>
<Route
strict
exact={true}
path="/mine"
component={Mine}
></Route>
<Route
strict
exact
path="/mine/ucenter"
component={UCenter}
></Route>
{/* <Route
path="/demo"
render={() => <div>Hello Demo</div>}
></Route> */}
<Route
path="/demo"
render={(props) => <Demo {...props} name="你好" />}
></Route>
<Route component={NotFound}></Route>
</Switch>
</Router>
</div>
);
}
export default App;
Parameters
App.js
import React from 'react';
import Home from './pages/Home';
import Mine from './pages/Mine';
// import { BrowserRouter as Router, Route } from 'react-router-dom';
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
import Nav from './components/Nav';
import UCenter from './pages/UCenter';
import NotFound from './pages/NotFound';
import Demo from './pages/Demo';
/**
* HashRouter: 秒点链接
* BrowserRouter: h5新特性 / history.push 如果上线之后,需要后台做一些处理:重定向处理 404bug
*/
/**
* /mine/ucenter 包含了 /mine
*/
function App() {
return (
<div className="App">
<Router>
<Nav></Nav>
<Switch>
<Route exact path="/" component={Home}></Route>
<Route
strict
exact={true}
path="/mine"
component={Mine}
></Route>
<Route
strict
exact
path="/mine/ucenter/:id?/:name?"
component={UCenter}
></Route>
{/* <Route
path="/demo"
render={() => <div>Hello Demo</div>}
></Route> */}
<Route
path="/demo"
render={(props) => <Demo {...props} name="你好" />}
></Route>
<Route component={NotFound}></Route>
</Switch>
</Router>
</div>
);
}
export default App;
components/Nav/index.jsx
import React from 'react';
import { NavLink } from 'react-router-dom';
import './style.css';
export default class Nav extends React.Component {
render() {
return (
<div>
<ul>
<li>
<NavLink
activeClassName="selected"
activeStyle={{ color: 'green' }}
exact
to="/"
>
Home页面(Link)
</NavLink>
</li>
<li>
<NavLink activeClassName="selected" exact to="/mine">
Mine页面(Link)
</NavLink>
</li>
<li>
<NavLink
activeClassName="selected"
exact
to="/mine/ucenter/1001/liang"
>
UCenter页面(Link)
</NavLink>
</li>
<li>
<a href="#/home">Home页面(a)</a>
</li>
<li>
<a href="#/mine">Mine页面(a)</a>
</li>
</ul>
</div>
);
}
}
pages/UCenter.jsx
import React from 'react';
const UCenter = (props) => {
return (
<div>
Hello UCenter: {props.match.params.id} - {props.match.params.name}
</div>
);
};
export default UCenter;
React-Router querystring读取参数
另外一种传参
pages/UCenter.jsx
import React from 'react';
import querystring from 'querystring';
const UCenter = (props) => {
const params = new URLSearchParams(props.location.search)
console.log(params);
console.log(params.get('name'));
const value = querystring.parse(props.location.search);
console.log(value);
return (
<div>
Hello UCenter: {props.match.params.id} - {props.match.params.name}
</div>
);
};
export default UCenter;
持续更新中......