react-router-dom 官方示例解读(上)

react-router-dom 官方示例解读

    • 说明
    • 官方文档
    • BasicExample--基础实例
    • UrlParams--动态路由
    • Nesting--嵌套路由
    • AuthRoute--路由鉴权

  • 学习资源推荐

  • 微信扫码关注公众号 :前端前端大前端,追求更精致的阅读体验 ,一起来学习啊
  • 关注后发送关键资料,免费获取一整套前端系统学习资料和老男孩python系列课程
    在这里插入图片描述

说明

该篇文章是对react-router-dom 官方示例的解读,例子有些会使用原始demo,有些为了方便理解会使用我自己写的。当然,如果有能力的话,还是推荐官方文档。

官方文档

  • doc

BasicExample–基础实例

分析

这是一个最基础的路由示例,根据不同的url渲染不同的组件。值得注意的是,对于Route组件而言,支持的渲染组件方式不唯一单标签的时候可以使用component属性,render属性,或者children属性挂载要渲染的组件。双标签的时候包裹要渲染的组件,也就是children…

import React from 'react'
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link
} from "react-router-dom";

const Home = () => <h2>Home</h2>
const About = () => <h2>About</h2>
const Dashboard = () => <h2>Dashboard</h2>
const News = () => <h2>News</h2>
const Games = () => <h2>Games</h2>

export default function () {
    return (
        <Router>
            <div>
                <ul>
                    <li> <Link to="/">Home</Link> </li>
                    <li>  <Link to="/about">About</Link>  </li>
                    <li>  <Link to="/dashboard">Dashboard</Link> </li>
                    <li>  <Link to="/news">News</Link> </li>
                    <li>  <Link to="/games">Games</Link> </li>
                </ul>
                <hr />
                <Switch>
                    <Route exact path="/"> <Home /></Route>
                    <Route path="/about" component={About} />
                    <Route path="/dashboard" children={<Dashboard />} />
                    <Route path="/news" render={()=><News />} />
                    <Route path="/games" component={()=><Games/>} />
                </Switch>
            </div>
        </Router>
    );
}

UrlParams–动态路由

分析

该示例演示了动态路由是如何匹配的,以及如何获取匹配到的参数值。和很多框架匹配规则一致,都是:param.在获取参数的时候,可以用hooks形式 ,也可以用原始的props.match.params.xxx

import React from "react";
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link,
    useParams
} from "react-router-dom";


export default function () {
    return (
        <Router>
            <div>
                <h2>Accounts</h2>
                <ul>
                    <li>
                        <Link to="/netflix/1">Netflix</Link>
                    </li>
                    <li>
                        <Link to="/zillow-group/2">Zillow Group</Link>
                    </li>
                    <li>
                        <Link to="/yahoo/3">Yahoo</Link>
                    </li>
                    <li>
                        <Link to="/modus-create/4">Modus Create</Link>
                    </li>
                </ul>
                <Switch>
                    <Route path="/:page/:num" component={Child} />
                </Switch>
            </div>
        </Router>
    );
}

function Child(props) {
    let { page} = useParams();
    let num=props.match.params.num;
    return (
        <div>
            <h3>
                当前页: {page}--数字:{num}
            </h3>
        </div>
    );
}

Nesting–嵌套路由

分析

嵌套路由适用于有明显层级划分的情况,以官方示例来看,主层级分为home和topics,topics又划分出三个子主题,这就涉及到了嵌套路由。子路由的url都是在父级路由基础上拼接出来的。像这样 /topics /topics/rendering。值得注意的是,这个案例里用到了一个新的hooks,useRouteMatch,这就相当于原始的props.match.此外,这个示例里对useRouteMatch()解构了path和url,如果你打印一下,你会发现它们的值是一样的,也许就像原文解释那样,一个用来获取父路径,一个用于Link组件的跳转,更规范?

import React from "react";
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link,
    useParams,
    useRouteMatch
} from "react-router-dom";

const Home = () => <h2>Home</h2>

const Topic = () => {
    let { topicId } = useParams();
    return <h3>{topicId}</h3>
}


const Topics = () => {

    let { path, url } = useRouteMatch();
    return (
        <div>
            <h2>Topics</h2>
            <ul>
                <li><Link to={`${url}/rendering`}>Rendering with React</Link></li>
                <li><Link to={`${url}/components`}>Components</Link></li>
                <li><Link to={`${url}/props-v-state`}>Props v. State</Link></li>
            </ul>
            <Switch>
                <Route exact path={path}> <h3>Please select a topic.</h3></Route>
                <Route path={`${path}/:topicId`} component={Topic} />
            </Switch>
        </div>
    );
}



export default function () {
    return (
        <Router>
            <div>
                <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/topics">Topics</Link></li>
                </ul>
                <hr />
                <Switch>
                    <Route exact path="/" component={Home} />
                    <Route path="/topics" component={Topics} />
                </Switch>
            </div>
        </Router>
    );
}

react-router-dom 官方示例解读(上)_第1张图片

AuthRoute–路由鉴权

分析

这是一个简化后的改写demo.核心是通过高阶组件+状态控制实现路由鉴权。在实际开发中,有些页面必须登录才可以访问,甚至不同身份的人看到的页面也是不一样的。public页面都可以访问,protected页面必须登录才可以访问。登录状态这里使用一个变量isLogin控制.Redirect 组件用于身份验证不通过时重定向处理,useHistory 钩子函数可获取历史记录接口,控制页面跳转。PrivateRoute 是一个高阶组件,对基础的Route进行了进一步封装,注意...rest,在这里相当于将高阶组件获取的path属性传递给Route

import React from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  Redirect,
  useHistory,
} from "react-router-dom";

let isLogin = false;

const LoginBtn = () =>   <button onClick={()=>{isLogin = true}}>登录</button>


const LoginOutBtn = () => {
  let history=useHistory();
  return <button onClick={()=>{isLogin = false;history.push("/login")}}>退出登录</button>
}

const Login = () => <LoginBtn/>

const Condition = ({ children }) => isLogin ? children : <Redirect to="/login" />

const PrivateRoute = ({ children, ...rest }) => {
  return (
    <Route   {...rest} render={() => <Condition children={children} />} />
  );
}


export default function () {
  return (
    <Router>

      <p><Link to={"/public"} >public</Link></p>
      <p><Link to={"/protected"}>protected</Link></p>
      <Switch>
        <Route exact path="/" render={() => <h3>home</h3>} />
        <Route path="/public" render={() => <h3>public</h3>} />
        <Route path="/login" component={Login} />
        <PrivateRoute path="/protected">
          <h2>已经登录 可查看-protected</h2>
          <LoginOutBtn/>
        </PrivateRoute>
      </Switch>
    </Router>
  )

}


你可能感兴趣的:(react)