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:感谢 & 参考 各路大神