react-router包含三个库:react-router、react-router-dom、react-router-native;react-router提供基本的路由功能,实际使用时不需要直接安装,根据运行环境选择react-router-dom(浏览器中)或react-router-native(rn中)
路由使用例子:
// ReactRouterPage.js
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
<Router>
<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Link to="/login">登录</Link>
{/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
{/**path如果不写,则一直匹配 */}
{/**Switch独占路由 匹配一个 */}
{/**什么都不写放在最后如404 */}
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/user" component={UserPage} />
<Route path="/login" component={LoginPage} />
<Route render={() => <div>404</div>} />
</Switch>
</Router>
</div>
);
}
}
动态路由:使用:id的形式定义动态路由
// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
<Router>
<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Link to="/login">登录</Link>
<Link to="/search/123">搜索</Link>
{/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
{/**path如果不写,则一直匹配 */}
{/**Switch独占路由 匹配一个 */}
{/**什么都不写放在最后如404 */}
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/user" component={UserPage} />
<Route path="/login" component={LoginPage} />
{/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
<Route path="/search/:id" component={SearchComponent} />
<Route render={() => <div>404</div>} />
</Switch>
</Router>
</div>
);
}
}
function SearchComponent(props) {
console.log(props, "search");
const { id } = props.match.params;
return <div>{id}</div>;
}
嵌套路由:
嵌套路由:
// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
<Router>
<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Link to="/login">登录</Link>
<Link to="/search/123">搜索</Link>
{/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
{/**path如果不写,则一直匹配 */}
{/**Switch独占路由 匹配一个 */}
{/**什么都不写放在最后如404 */}
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/user" component={UserPage} />
<Route path="/login" component={LoginPage} />
{/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
<Route path="/search/:id" component={SearchComponent} />
<Route render={() => <div>404</div>} />
</Switch>
</Router>
</div>
);
}
}
function DetailComponent(props) {
return <div>DetailComponent</div>;
}
function SearchComponent(props) {
console.log(props, "search");
const { id } = props.match.params;
return (
<div>
searchComponent-{id}
{/**嵌套路由 */}
<Link to={"/search/" + id + "/detail"}>详情</Link>
<Route path={"/search/:" + id + "/detail"} component={DetailComponent} />
</div>
);
}
路由守卫:
// src/index.js
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { Provider } from "react-redux";
import store from "./store/index";
// 把Provider放在根组件外层,使得子组件都能获得store
ReactDOM.render(
<Provider store={store}>
<App />,
</Provider>,
document.getElementById("root")
);
// src/App.js
import React from "react";
import RouterPage from "./pages/RouterPage.js";
function App() {
return (
<div className="App">
<RouterPage />
</div>
);
}
export default App;
// store/index.js
import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import logger from "redux-logger";
const initalUserInfo = {
isLogin: false,
user: { name: null },
};
// 定义修改规则
function countReducer(state = 0, action) {
switch (action.type) {
case "ADD":
return state + 1;
case "MINUS":
return state - 1;
default:
return state;
}
}
// 定义修改规则 登录
function loginReducer(state = { ...initalUserInfo }, action) {
switch (action.type) {
case "LOGIN_SUCCESS":
return {
isLogin: true,
user: { name: "xss" },
};
case "LOGOUT_SUCCESS":
return {
isLogin: false,
user: { name: null },
};
default:
return state;
}
}
const store = createStore(
combineReducers({ user: loginReducer }, countReducer),
applyMiddleware(thunk, logger)
);
export default store;
// pages/RouterPage.js
// react-router包含3个库,react-router、react-router-dom、react-router-native;
// react-router提供最基本的路由功能,实际使用时不要直接安装react-router,而是根据运行
// 环境选择安装react-router-dom(浏览器中)还是react-router-native(rn中);
// react-router-dom和react-router-native都依赖react-router,所以在安装时,
// react-router也会自动安装,创建web应用
// npm i --save react-router-dom
// react-router中奉行一切皆组件的思想,路由器Router、链接Link、
// 路由Route、独占Switch、重定向Redirect都以组件形式存在
import React, { Component } from "react";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import HomePage from "./HomePage";
import UserPage from "./UserPage";
import LoginPage from "./LoginPage";
import PrivateRoute from "./PrivateRoute";
export default class RouterPage extends Component {
render() {
return (
<div>
<h3>RouterPage</h3>
<Router>
<Link to="/">首页</Link>
<Link to="/user">用户中心</Link>
<Link to="/login">登录</Link>
<Link to="/search/123">搜索</Link>
{/*Route一定要包裹在Router之内,因为Route要使用history location,而这些都来自于Router */}
{/**path如果不写,则一直匹配 */}
{/**Switch独占路由 匹配一个 */}
{/**什么都不写放在最后如404 */}
<Switch>
<Route exact path="/" component={HomePage} />
{/**路由守卫 */}
<PrivateRoute path="/user" component={UserPage} />
{/**<Route path="/user" component={UserPage} />*/}
<Route path="/login" component={LoginPage} />
{/**动态路由 使⽤:id的形式定义动态路由 使⽤:id的形式定义动态路由 <Link to={"/search/" + searchId}>搜索</Link>*/}
<Route path="/search/:id" component={SearchComponent} />
<Route render={() => <div>404</div>} />
</Switch>
</Router>
</div>
);
}
}
function DetailComponent(props) {
return <div>DetailComponent</div>;
}
function SearchComponent(props) {
console.log(props, "search");
const { id } = props.match.params;
return (
<div>
searchComponent-{id}
{/**嵌套路由 */}
<Link to={"/search/" + id + "/detail"}>详情</Link>
<Route path={"/search/:" + id + "/detail"} component={DetailComponent} />
</div>
);
}
// pages/PrivateRoute.js
import React, { Component } from "react";
import { Route, Redirect } from "react-router-dom";
import { connect } from "react-redux";
export default connect(({ user }) => ({ isLogin: user.isLogin }))(
class PrivateRoute extends Component {
render() {
const { isLogin, path, component } = this.props;
if (isLogin) {
return <Route path={path} component={component} />;
} else {
return (
<Redirect
to={{
pathname: "/login",
state: {
redirect: path,
},
}}
/>
);
}
}
}
);
// pages/LoginPage.js
import React, { Component } from "react";
import { Redirect } from "react-router-dom";
import { connect } from "react-redux";
export default connect(
// mapStateToProps
({ user }) => ({ isLogin: user.isLogin }),
// mapDispatchToProps
{
login: () => ({ type: "LOGIN_SUCCESS" }),
}
)(
class LoginPage extends Component {
render() {
const { isLogin, login, location } = this.props;
// 如果已经登录,则跳回之前PrivateRoute.js存储的页面路径state中的redirect
// 如果直接输入路由login而不是从PrivateRoute页面进来会报错,要给个默认值
const { redirect = "/" } = location.state || {};
if (isLogin) {
return <Redirect to={redirect} />;
} else {
return (
<div>
<h3>LoginPage</h3>
<button onClick={login}>login</button>
</div>
);
}
}
}
);
// pages/UserPage.js
import React, { Component } from "react";
import { connect } from "react-redux";
export default connect(({ user }) => ({ isLogin: user.isLogin }), {
logout: () => ({ type: "LOGOUT_SUCCESS" }),
})(
class UserPage extends Component {
render() {
const { logout } = this.props;
return (
<div>
UserPage
<button onClick={logout}>logout</button>
</div>
);
}
}
);
// pages/HomePage.js
import React, { Component } from "react";
import "./HomePage.less";
export default class HomePage extends Component {
render() {
return (
<div className="homepage">
<h3>HomePage</h3>
</div>
);
}
}
Route渲染内容的三种方式及其优先级:children》component》render
ps:感谢 & 参考 各路大神