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: "张三"
}

 

 

 
posted @ 2019-01-20 22:51  真的想不出来  阅读(482)  评论(0编辑  收藏  举报