zoukankan      html  css  js  c++  java
  • 3.React-router/BrowserRouter/withRouter/Switch/history/exact/strict/Link/Redirect/PropTypes

    先了解下基础知识

    路径可能的样子: http://localhost:9000/static/index/posts/edit?name=张三&age=12&gender=man#zh/en/年龄
    一段完整的地址: 协议           端口                  路径(/...)                  search(?key=value&k=v&...)      hash(#...)
     
    以前后台接收到前端的请求,不但要发送数据给前端还要返回页面
    前端路由,切换页面不需要服务器返回,减少了服务器压力、单页应用
    公共资源只需要请求一次即可,前端的职责就更多,前端比重就较高(逻辑多了)

    安装路由:

      npm i react-router-dom

    history 路由:(浏览器历史记录管理)

      在服务器下访问,添加浏览器历史记录的
      history.pushState (数据,'浏览器都忽略的名字',你显示的 url 地址)
      onpopstate
        当你触发了浏览器的前进或者后退就会触发这个事件
        在这个事件中,ev 下有 state 属性,可以接收到 pushState 时的数据
      history.length 查看历史记录中的个数(据说最高是50个)
      back() (回退)
      forward() (前进)
      go() ( go(-3) 后退3步 )
      push()    跳转路由
     this.props.history.push({
        pathname: "/xxx/路径/...", 
        params: {  // 跳转后带出的信息
            a: xxxx,
            b:xxxx
        } 
    })
    
    // 获取信息  console.log(this.props.location.params)
      replace()  (替换掉当前的 history 记录)
     

    React 中如何使用路由

    BrowserRouter : (浏览器路由)

    1:import {BrowserRouter as Router} from 'react-router-dom';    
      hash路由:import {HashRouter as Router} from 'react-router-dom';  // 会有#号
     
    2:引入把Router包在ReactDOM.render(根下);
      比如:
        ReactDOM.render(<Router><App /></Router>);

    3:配置路由:
      import {Route} from 'react-router-dom';
      <Route path="/home" component={组件}/>
    3.1:component={组件}也可以是一个函数( 函数声明组件)
    <Route path="/home" component={(props)=>{
        return <div>1234</div>
        // return <Ppa/>
    }}/>
      props:
        在切换路由的时候记录的细节信息,是函数的情况下,要传入路由细节。
        在组件中,可以通过 this.props 去查看、使用:

        match  ->  params、url、path           (获取,params 动态路由 :id)
        location  ->  hash、search、state  (获取,hash #号后面  /  search ?号后面)
        history  ->  go() 、push()、 replace() 、 ...   (改变路由,进行页面的跳转)

      一般使用component的函数,都是使用函数声明组件。
      注意:
        component 如果放函数,一定要放有名的函数组件,
        不然(匿名函数)点击多次本路由,会多次挂载和卸载
        当组件拿不到 props 下,路由的相关信息时,可以使用 withRouter 去包一下
      一般判断使用可选组件,使用 render={(props)=>{}}
     
    3.2:render 可以返回 jsx 或者一个组件,更喜欢通过 render 去判断使用需求的组件。

    3.3:children 跟一个函数,不管你匹不匹配path都执行组件。
     
    4. 特性:
      默认配置如果/下有组件,那么所有关于/xxx都吃得到/下的这个组件
      如果,/下匹配组件,/下的xxx不想匹配/这个组件,那么可以在Route 下
      加一个 exact
     
    exact: 不写默认是 false
      若果 /father 写了 exact 那么 /father/child 只会匹配到 /father ,所以建议在子路由中添加。
      /one    /one/two    true    no
      /one    /one/two    false   yes
     
    strict: 严格匹配,默认 false
      在 path 为 /detail/ 没有加 strict 那么 url 为 /detail 是能够匹配的
      加了 strict 的时候,能匹配 /detail/ 或者 /detail/xxx
     
    可以2个一起用:
    <Route path="/one" exact strict component={About}/>

    Link (跳转)  
      to=对象,带参数跳转(pathname, query, hash, state(额外数据)),注意:这些参数都被存放到 this.props.location 中
    import React, { Component } from 'react';
    import { Link } from 'react-router-dom';
    
    class About extends Component {
      render() {
        console.log(this.props)
        return (
          <div>
            <Link to={{
              pathname: "/jump/url",
              hash: '#ahash',
              query: { foo: 'foo', boo: 'boo' },
              state: { data: 'hello' }
            }}>
            </Link>
          </div>
        );
      }
    }
    
    export default About;
    Redirect (重定向)
      1.引包:import { Redirect } from 'react-router-dom';
      2.<Redirect to="/dashboard"/>   等同于调用了 replace() ,替换了当前的 url
      to后面可以跟字符串(路径即可),
      还可以跟对象(to={{pathname:'/',search:'?a=1&b=2'}})
      存放数据
    Switch:从上到下去读,只匹配一个
      当路由既有动态路由,又有静态路由
        /about/:id  动态
        /about/d 静态
      输入静态路由的时候,会匹配到动态路由(2个组件都会显示)  
      要求是:输入静态路由只显示静态。这个时候就要用 Switch
      
      1.引包:import { Switch } from 'react-touter-dom'
     
      2.组件:
        <Switch>
          /about/d
          /about/:id
        </Switch>
    import React, { Component } from 'react';
    import { Route,Link,Switch, Redirect } from 'react-router-dom';
    import Home from './component/home';
    import About from './component/about';
    import Aboutc from './component/aboutc';
    import Aboutd from './component/aboutd';
    
    class App extends Component {
     
      render() {
        return (
          <div>
            <Link to='/'><button>首页</button></Link>
            <Link to='/about'><button>关于</button></Link>
            <Route exact path='/' component={Home}/>
            <Route path='/about' render={(props)=>{
              return <About {...props}/>
            }}/>
            <Switch>
              <Route path='/about/d' component={Aboutd}/>
              <Route path='/about/:id' component={Aboutc}/>
          <Redirect from="/* to="/"> // 重定向,路径发生错误,会 to 到指定的默认路径 </Switch> </div> ); } } export default App;

     (当组件拿不到 props 的时候,可以使用 withRouter 去包一下)

    withRouter
      高阶组件:源于高阶函数(参数为函数,返回一个新的函数(或者一类运算结果))
        function fn(f){
          return f.bind(document)
        }
      高阶组件:传一个组件,返回另外一个组件
      1.引包:import { withRouter } from 'react-router-dom'
      2.导出:export default withRouter(BackHome)     
    import React, { Component } from 'react';
    import {withRouter} from 'react-router-dom';
    class BackHome extends Component {
    
        back = () => {
            this.props.history.push('/');
        }
        render() { 
            return (
                <div>
                   <button onClick={this.back}>返回首页</button>
                </div>
            );
        }
    }
    export default withRouter(BackHome);

    PropTypes: 能够验证父级传递进来的数据类型(为了报错)

    import PropTypes from 'prop-types';
    
    PPa.propTypes = {
        name: PropTypes.string
        //num:PropTypes.number
        //num:PropTypes.数据类型
    }
    PPa.defaultProps = { // 设置默认值
        name: "张三"
    }
     
  • 相关阅读:
    传纸条
    金明的预算方案
    矩阵取数
    能量项链
    选择客栈
    过河
    乌龟棋
    逢低吸纳
    三角形牧场
    多米诺骨牌
  • 原文地址:https://www.cnblogs.com/MrZhujl/p/10296545.html
Copyright © 2011-2022 走看看