React-router

用到的插件

react-router-dom的理解

1.react的一个插件库。 2.专门用来实现一个SPA应用。

import {
  HashRouter,
  BrowserRouter,
  Link,
  NavLink,
  Route,
  Switch,
  Redirect,
} from "react-router-dom";

HashRouter, BrowserRouter

这两个是设置哈希模式,与history模式,需要套在最外层的标签

当时history的时候刷新会出现404,所以需要在webpack里面配置

设置:

 historyApiFallback: {
      // Paths with dots should still use the history fallback.
      // See https://github.com/facebook/create-react-app/issues/387.
      disableDotRule: true,
      //index: paths.publicUrlOrPath,
    },

Route相当于router-view 用来根据地址栏匹配显示对应的组件

path 匹配的路径

component 是要渲染的组件 并且将路由对象映射到props

组件标签中渲染的路由组件 默认不会注入路由对象

exact 精准匹配只有path和路径完全匹配才会渲染,注意在有嵌套路由的地方不要精准匹配

switch 万里挑一 只返回第一个匹配到的元素

redirect 重定向注意死循环

 <Switch>
            <Redirect exact from="/" to="/home"></Redirect> 
//重定向,注意前面要加精准匹配,exact,防止死循环
            <Route path="/my">
              <My></My> //这样写没办法传参
            </Route>
            //下面是嵌套路由,注意不要写精准匹配
            <Route  path="/user" component={() => {
              return(<div>
                {/* <h2>这里是user</h2> */}
                <User></User>
                <NavLink  to="/user/info">用户信息</NavLink>
                <NavLink  to="/user/login">用户登录</NavLink>
                <hr />
                <Route path="/user/info" component={UserInfo}></Route>
                <Route path="/user/login" component={UserLogin}></Route>
              </div>)
            }}></Route>
            <Route path="/home/:id/:ps" component={Home}></Route>//动态路由传参
            <Route path="/home" component={Home}></Route>
            {/* 嵌套路由 */}
            {/* 404 */}
           {  <Route component={NotFound}></Route>}  //路径都不对的时候,跳404,写在最后面,不用写path
          </Switch>

路由传参的方法

1.params参数
    路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
    注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
    接收参数:this.props.match.params
2.search参数
    路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
    注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
    接收参数:this.props.location.search
    备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
3.state参数
    路由链接(携带参数):<Link to={{pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
 history.push("/home", { us: 123, ps: 123 });
   

注意:正经通过state传参刷新后值不会丢 

  <NavLink to={{pathname:"/my",hehe:{name:'hehe'}}} activeClassName={styles.red}>
  //这里用hehe代替state就可以了

withRouter

也是一个高阶组件 从context 获取路由对象 映射到组件的props,如果在你想在一般组件使用 路由组件所特有的API 时, 就要借助 withRouter withRouter可以加工一般组件, 让一般组件具备路由组件所特有的API,存在这个组件的this.props.history,就是为了把普通组件转换成路由组件,withRouter 提供给组件路由对象 只有在BrowserRouter 和 hashRouter内部的才可以使用

普通组件与路由组件

路由组件与一般组件props接收的数据对比图:

在这里插入图片描述

 路由组件与一般组件的不同之处

1.写法不同:
    一般组件: <Demo/>
    路由组件: <Route path="/demo" component={Demo}/>
2.存放位置不同:
    一般组件: components
    路由组件: pages
3.接收到的props不同:
	一般组件: 写组件标签时传递了什么,就能收到什么
	路由组件: 接收带三个固定的属性
		history:
            go: ƒ go(n)
            goBack: ƒ goBack()
            goForward: ƒ goForward()
            push: ƒ push(path, state)
            replace: ƒ replace(path, state)
        location: 
            pathname: "/home"
            search: ""
            state: undefined
        match:
            params: {}
            path: "/home"
            url: "/home"

渲染路由组件的方式

componet props里直接有路由对象 函数组件和类组件都一样

const Home = (props) => {
  return <div>这里是home</div>;
//在这里直接可以通过props接收跳转的参数
};


<Route path="/home" component={Home}></Route>

直接写组件名字渲染slot

slot props没有路由对象  函数组件可以通过hooks获取  类组件 withrouter获取

 import {useHistory, useLocation,useParams,useRouteMatch,} from "react-router-dom";

函数组件

const Home = (props) => {
  console.log(props);
  const history = useHistory(); 
  const location = useLocation();
  const params = useParams();
  const routeMatch = useRouteMatch();//通过这四个参数传路由对象

  console.log("history", history);
  console.log("location", location);
  console.log("params", params);
  console.log("routeMatch", routeMatch);
  return <div>这里是home</div>;
};



 <Route path="/home">
              <Home></Home>
            </Route>

 render

render不能跟组件 只能跟函数 在函数里返回组件 函数可以将props传递给组件

例如

函数组件

//这是一个函数组件
const Home = (props) => {
  console.log(props);
  return <div>这里是home</div>;
                            
};

 <Route path="/home" render={(props) => {
    return <Home {...props}></Home>; }}>
</Route>  //这样传参也行



//但是里面不能用hooks那四个函数
const Home = (props) => {
  console.log(props);
  return <div>这里是home</div>;
                            
};
//或者
 <Route path="/home" render={Home}></Route>





类组件

import React, { Component } from "react";
class HomeClass extends Component {

  state = {};

  render() {
    return <div>app组件</div>;
  }

  componentDidMount() {
    console.log(this)
  }
}
export default HomeClass;





//类组件进行传参
<Route path="/home" render={(props) => {
               return <HomeClass {...props}></HomeClass>
             }}>
</Route> //是一样的

chilren

render不能跟组件 只能跟函数 在函数里返回组件 函数可以将props传递给组件,不管是否匹配都会显示

例如:

 <Route path="/h" render={(props) => {
               return <HomeClass {...props}></HomeClass>
             }}></Route>
<Route path="/home" children={(props) => {
               return<Home></Home>
             }}></Route>
//当你地址不论是什么children渲染的组件都会出来,上面这个例子,在你用http://localhost:3000/h
这时候,HomeClass 组件与Home都会渲染出来

//拿children渲染的组件参数的时候上面return的是slot样式,所以用hooks的方法

<Route path="/home/1/2/2/3/" children={(props) => { //不管path写什么都会跳转
               return<Home {...props}></Home>
             }}></Route> //这个就直接能拿到props

//类组件也是通过传递props,通过withrouter获取
<Route path="/home" children={(props) => {
               return<HomeClass {...props}></HomeClass>
             }}></Route> 

 当你路由是h与children渲染组件的路由不匹配,但是也会渲染

函数组件自己封装Router

例子:做一个路由拦截,在redux里面并没有路由守卫钩子函数

先封装一个组件,把要跳转的path路径传递到组件里面,组件拿到传递过来的path进行router,从而来进行路由拦截

AuthComponent.js

知识点: const { path, children } = props //注意这里需要从props里面取path,在index会用,

import React, { useContext } from "react";
import { Route, Redirect, useLocation } from "react-router-dom";
import userContext from "./userContext";
function AuthComponent(props) {
  const user = useContext(userContext);
  const location = useLocation()
  console.log("location", location)
  
  console.log(user);
   const { path, children } = props //注意这里需要从props里面取path,在index会用,
  return (
    <div>
      <Route path={path}> //从这里把path传递出去
        {user.user ? (  //下面的三元是判断user是否是真,若是真就不拦截,是假就重定向
          children
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: location },
            }}
          />
        )}
      </Route>
    </div>
  );
}
export default AuthComponent;

在index用的时候,不在用router,而是用自己封装的

   <Switch>
              <Route path="/public">
                <PublicPage />
              </Route>
              <Route path="/login">
                <LoginPage />
              </Route>
              <AuthComponent path={"/protected"}> //这里就能传递到组件内部了,在组件里面进行props进行获取就行 也可以path="/protected" 这样传
                <ProtectedPage /> //这里就是插槽
              </AuthComponent>
            </Switch>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值