react-router
:提供最基本的路由功能,实际使⽤的时候我们不会直接安装react-router,⽽是根据应⽤运⾏的环境选择安装react-router-dom(在浏览器中使⽤)或react-router-native(在rn中使⽤)react-router-dom
:都依赖react-router,所以在安装时,react-router也会⾃动安装,创建web应⽤react-router-native
:同上npm install --save react-router-dom
react-router中奉⾏⼀切皆组件的思想,路由器-Router、链接-Link、路由-Route、独占-Switch、重定向-Redirect都以组件形式存在。
创建RouterPage.js
import React, { Component } from "react";
import { BrowserRouter, Link, Route } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
export default class RouterPage extends Component {
render() {
return (
<div>
<h1>RouterPage</h1>
<BrowserRouter>
<nav>
<Link to="/">⾸⻚</Link> <Link to="/user">⽤户中⼼</Link>
</nav>
{/* 根路由要添加exact,实现精确匹配 */}
<Route exact path="/" component= {HomePage}/>
<Route path="/user" component= {UserPage} />
</BrowserRouter>
</div>
);
}}
Route渲染优先级:children>component>render。
三者能接收到同样的[route props]
,包括match, location and history,但是当不匹配的时候,children的match为null。
这三种⽅式互斥,你只能⽤⼀种,它们的不同之处可以参考下⽂
使用场景:有时候,不管location是否匹配,你都需要渲染⼀些内容,这时候你可以⽤children。除了不管location是否匹配都会被渲染之外,其它⼯作⽅法与render完全⼀样。
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Link, Route } from "react-router-dom";
function ListItemLink({ to, name, ...rest }) {
return (
<Route path={to}
children={({ match }) => (
<li className={match ? "active" : ""}>
<Link to={to} {...rest}>{name} </Link>
</li>
)}
/>
);
}
export default class RouteChildren extends Component {
render() {
return (
<div>
<h3>RouteChildren</h3>
<Router>
<ul>
<ListItemLink to="/somewhere" name="链接1" />
<ListItemLink to="/somewhere-else"name="链接2" />
</ul>
</Router>
</div>
);
}}
但是当你⽤render的时候,你调⽤的只是个函数。但是它和component⼀样,能访问到所有的[route props]
。
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route } from "react-router-dom";
// ⽅便的内联渲染
ReactDOM.render(
<Router>
<Route path="/home" render={() => <div>Home</div>} />
</Router>,
node
);
// wrapping/composing
//把route参数传递给你的组件
function FadingRoute({ component: Component,...rest }) {
return (
<Route
{...rest}
render={routeProps => (
<Component {...routeProps} />
)}
/>
);
}
ReactDOM.render( <Router> <FadingRoute path="/cool" component= {Something} />
</Router>,
node
);
场景:只在当location匹配的时候渲染。
import React, {Component, useEffect} from "react";
import {BrowserRouter as Router, Route} from "react-router-dom";
export default class RouteComponePage extends
Component {
constructor(props) {
super(props);
this.state = {
count: 0
};
}
render() {
const {count} = this.state;
return (
<div>
<h3>RouteComponePage</h3>
<button onClick={() => {
this.setState({count: count + 1});
}}>
click change count {count}
</button>
<Router>
<Route render={() => <FunctionChildcount={count} />} />
<Route children={() => <FunctionChildcount={count} />} />
</Router>
</div>
);
}
}
class Child extends Component {
componentDidMount() {
console.log("componentDidMount"); //sy-log
}
componentWillUnmount() {
console.log("componentWillUnmount"); //sylog
}
render() {
return <div>child-{this.props.count}</div>;
}
}
function FunctionChild(props) {
useEffect(() => {
return () => {
console.log("WillUnmount"); //sy-log
};
}, []);
return <div>child-{props.count}</div>; }
使⽤:id
的形式定义动态路由
定义路由
<Route path="/search/:id" component={Search} />
添加导航链接
<Link to={"/search/" + searchId}>搜索</Link>
创建Search组件并获取参数
import React, { Component } from "react";
import { BrowserRouter, Link, Route } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
function Search({ match, history, location }) {
const { id } = match.params;
return (
<div>
<h1>Search: {id}</h1>
</div>
);
}
export default class RouterPage extends
Component {
render() {
const searchId = "1234";
return (
<div>
<h1>RouterPage</h1>
<BrowserRouter>
<nav>
<Link to="/">⾸⻚</Link>
<Link to="/user">⽤户中⼼</Link> <Link to={"/search/" + searchId}>搜 索</Link>
</nav>
{/* 根路由要添加exact,实现精确匹配 */}
<Route exact path="/" component= {HomePage}/>
<Route path="/user" component= {UserPage} />
<Route path="/search/:id" component= {SearchComponent} />
</BrowserRouter>
</div>
);
}}
嵌套路由
Route组件嵌套在其他⻚⾯组件中就产⽣了嵌套关系。
修改上面的组件Search,添加新增和详情:
function DetailComponent(props) {
return <div>DetailComponent</div>; }
function SearchComponent(props) {
console.log("props", props); //sy-log
const {id} = props.match.params;
return (
<div>
<h3>SearchComponent</h3>
<p>{id}</p>
<Link to={"/search/" + id + "/detail"}>详 情</Link>
<Route path="/search/:id/detail" component={DetailComponent} />
</div>
);
}