溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

手挽手帶你學(xué)React之React-router4.x的使用

發(fā)布時間:2020-10-16 01:21:47 來源:腳本之家 閱讀:154 作者:蔣吉兆 欄目:web開發(fā)

手挽手帶你學(xué)React入門三檔,帶你學(xué)會使用Reacr-router4.x,開始創(chuàng)建屬于你的React項目

什么是React-router

React Router 是一個基于 React 之上的強大路由庫,它可以讓你向應(yīng)用中快速地添加視圖和數(shù)據(jù)流,同時保持頁面與 URL 間的同步。通俗一點就是,它幫助我們的程序在不同的url展示不同的內(nèi)容。

為什么要用React-router

我們開發(fā)的時候,不可能所有的東西都展示在一張頁面上,在業(yè)務(wù)場景的要求下,我們要根據(jù)不同的URL或者不同的哈希來展示不同的組件,這個我們可以稱它為路由。在我們不使用React-router的時候,我們?nèi)绾稳プ雎酚赡兀?/p>

我在這里給大家舉個例子,不使用React-router,來實現(xiàn)一個簡單路由。

  // App.js
import React,{Component} from 'react'
export default class App extends Component {
  constructor(){
    super()
  // 我們在App.js內(nèi)部來渲染不同的組件 我們這里采用哈希路由的方式,鑒于React的渲染機制,我們需要把值綁定進入state內(nèi)部。
    this.state={
      route:window.location.hash.substr(1)
    }
  }
  componentDidMount() {
    // 這里我們通過監(jiān)聽的方式來監(jiān)聽哈希的變化,并且來更新state促進視圖更新
    window.addEventListener('hashchange', () => {
      console.log(window.location.hash.substr(1))
     this.setState({
      route: window.location.hash.substr(1)
     })
    })
   }
  render() {
    //在這里我們定義一個RouterView 所有的變化后的組件都會丟到這個RouterView中
    let RouterView = App
    switch (this.state.route) {
      case '/children1':
      RouterView = Children
        break;
      case '/children2':
      RouterView = ChildrenTwo
        break;
      default:
      RouterView = Home
        break;
    }
    return (
      <div>  
        <h2>App</h2>
        <ul>
          <li><a href="#/children1" rel="external nofollow" >children1</a></li> 
          {/* 點擊更改哈希值 這里觸發(fā)我們的監(jiān)聽 然后修改state來觸發(fā)組件的重新傳染 */}
          <li><a href="#/children2" rel="external nofollow" >children2</a></li>
        </ul>
        <RouterView/>
      </div>
    )
  }
}

// 為了展示效果定義子組件一

class Children extends Component{
  constructor(){
    super()
    this.state={
      
    }
  }
  render(){
    return(
      <div>
        <h2>我是子組件1</h2>
        
      </div>
    )
  }
}

// 為了展示效果定義子組件二

class ChildrenTwo extends Component{
  constructor(){
    super()
    this.state={
    
    }
  }
  render(){
    return(
      <div>
        <h2>我是子組件2</h2>
      </div>
    )
  }
}
// 為了展示效果定義Home組件
class Home extends Component{
  constructor(){
    super()
  }
  render(){
    return(
      <h2>我是Home</h2>
    )
  }
}

這樣我們通過監(jiān)聽哈希變化的方式實現(xiàn)了我們的第一個簡單路由,是不是對于路由的原理有了那么一丟丟的認識呢?接下來我們想象一個場景,這么一個路由出現(xiàn)了/children1/user/about/1,看到這里是不是覺得,用switch case已經(jīng)蒙B了?我們接下來就要使用到React-router了,這個東西可不需要我們自己去寫一大串的switch case了,并且性能啊,整潔度啊等等等方面都比我們自己寫的好多了!

React-router 初體驗

首先我們在React項目文件目錄下執(zhí)行

npm install react-router-dom --save
npm install react-router --save

要想體驗一個新的東西,當(dāng)然是要拿自己開刀 我們改進上面我們寫過的組件

// App.js
import React,{Component} from 'react'
// 首先我們需要導(dǎo)入一些組件...
import { HashRouter as Router, Route, Link } from "react-router-dom";
// 這里有BrowserRouter 和 HashRouter 兩種模式 我比較推薦HashRouter來學(xué)習(xí) BrowserRouter需要后端配合 單獨前端設(shè)置 刷新會出現(xiàn)404
// 然后我們把App組件整理干凈,大概成這個樣子
export default class App extends Component {
  constructor(){
    super()
    this.state={
     
    }
  }
  render() {
    return (
      <Router>
        <div>
        <h2>App</h2>
        <ul>
          <li> <Link to="/">Home</Link></li> 
          <li><Link to="/children1/">children1</Link></li>
          <li><Link to="/children2/">children2</Link></li>
        </ul>
        <Route exact path="/" component={Home} />
        <Route path="/children1" component={Children} />
        <Route path="/children2" component={ChildrenTwo} />
        </div>
      </Router>
    )
  }
}

// 為了展示效果定義子組件一
class Children extends Component{
  constructor(){
    super()
    this.state={
      
    }
  }
  render(){
    return(
      <div>
        <h2>我是子組件1</h2>
      </div>
    )
  }
}
// 為了展示效果定義子組件二
class ChildrenTwo extends Component{
  constructor(){
    super()
    this.state={
    
    }
  }
  render(){
    return(
      <div>
        <h2>我是子組件2</h2>
      </div>
    )
  }
}
// 為了展示效果定義Home組件
class Home extends Component{
  constructor(){
    super()
  }
  render(){
    return(
      <h2>我是Home</h2>
    )
  }
}

這里我們就完成了React-router4.X的初步體驗,怎么樣~我給大家的第一次的感覺還可以吧~

基本組件

Routers

在React-router4.0中,Routers有兩個表現(xiàn)方式 <BrowserRouter> <HashRouter> 這兩個標(biāo)簽都將會給你創(chuàng)建一個專門的history對象,BrowserRouter的表現(xiàn)模式需要搭配一個可以響應(yīng)請求的服務(wù)器。HashRouter是靜態(tài)文件服務(wù)器,我們本地開發(fā)的時候,建議使用HashRouter。這里需要注意一下,BrowserRouter和 HashRouter標(biāo)簽下面,只允許存在一個標(biāo)簽 具體寫法如下

<BrowserRouter>
  <div>
    {/*其余內(nèi)容寫在這里面*/}
  </div>
</BrowserRouter>

<HashRouter>
  <div>
    {/*其余內(nèi)容寫在這里面*/}
  </div>
</HashRouter>

Route

注意,最外層的是Router 這里是 Route 這是我們的路由匹配組件,它有兩個 Route和Switch

Route 組件擁有多個屬性,這在我們后期的路由傳參中將會用到。這里我們需要簡單了解幾個屬性 path component exact strict

path 是我們匹配的地址,當(dāng)?shù)刂菲ヅ涞臅r候 我們才會去渲染 component內(nèi)的組件內(nèi)容

path 后面如果書寫模式帶了 /: 這樣的內(nèi)容,那么這里將會成為占位符 我們可以利用占位符來取到對應(yīng)路徑的參數(shù) 使用 this.props.match.params+占位符的名字 即可拿到

exact 屬性來規(guī)定我們是否嚴格匹配

strict 則是嚴格匹配模式 我們規(guī)定的路徑使用/one/來書寫 如果沒有完全匹配 /one/ 則不會展示

<Route exact path="/one" component={App} />
// 這里我們加了exact 那么 路徑完全等于/one的時候才會渲染App /one/ one /one/two 后面這三種情況均不會渲染App

// 相反 如果我們沒有加 exact 的時候 /one /one/two App都會被渲染

<Route strict path="/one/" component={App} />
// 我們加了 strict 以后 /one 將不會渲染App 而如果沒有 strict 這種情況下 /one 是可以渲染App的

同時React-router給我們提供了一個Switch標(biāo)簽 在這個標(biāo)簽內(nèi) 我們只會渲染一個Route 并且使第一個符合條件的Route 這是什么意思呢?我們來看代碼

<Route path="/about" component={About} />
<Route path="/:User" component={User} />
<Route path="/" component={Home} />
<Route component={NoMatch} />

在這樣的路由下 我們匹配/about 會發(fā)現(xiàn) 所有的路由都可以匹配到并且渲染了出來,這肯定不是我們想要的結(jié)果 于是我們給它嵌套一個 Switch

<Switch>
  <Route path="/about" component={About} />
  <Route path="/:User" component={User} />
  <Route path="/" component={Home} />
  <Route component={NoMatch} />
</Switch>

這時候我們就只會匹配到第一個/about,僅僅渲染About,大家根據(jù)實際需求去決定是否嵌套Switch使用

Link和NavLink

Link 主要api是to,to可以接受string或者一個object,來控制url。我們代碼里看看書寫方法

  <Link to='/one/' /> 
  // 這就是路由到one 搭配Router使用 當(dāng)然我們可以使用一個對象

  <Link to={{
    pathname:'/one',
    search:'?name=qm',
    hash:'#two',
    state:{
      myName:'qimiao'
    }
  }} />
  // 這樣我們點擊link不僅可以到one 還可以傳遞一些參數(shù)

NavLink 它可以為當(dāng)前選中的路由設(shè)置類名、樣式以及回調(diào)函數(shù)等。使用如下

  <NavLink exact activeClassName='navLink' to='/one/' /> 
  // 這就是路由到one 搭配Router使用 當(dāng)然我們可以使用一個對象

  <NavLink exact activeClassName='navLink' to={{
    pathname:'/one',
    search:'?name=qm',
    hash:'#two',
    state:{
      myName:'qimiao'
    }
  }} />
  // 這里的exact 同樣是嚴格比配模式 同Route
  // 這樣我們可以為當(dāng)前選中的路由設(shè)置樣式了

子路由的書寫

在react-router4之前的版本,子路由通過路由嵌套就可以實現(xiàn)了,但是這一個方法到了React-router4中就行不通了

先來一個之前的寫法,當(dāng)然也是錯誤示例

export default class App extends Component {
  constructor(){
    super()
    this.state={
     
    }
  }
  render() {
    return (
      <Router>
        <div>
        <h2>App</h2>
        <ul>
          <li> <Link to="/home">Home</Link></li> 
          <li><Link to="/children1/">children1</Link></li>
          <li><Link to="/children2/">children2</Link></li>
        </ul>
        <Route path="/home" component={Home} >
          <Route path="children1" component={Children} />
          <Route path="children2" component={ChildrenTwo} />
          {/*在4.0以后的版本這樣都會報錯 那么我們應(yīng)該怎么寫呢*/}
        </Route>
      
        </div>
      </Router>
    )
  }
}

在react-router4.x版本中 我們子路由必須要在子組件內(nèi)部了

export default class App extends Component {
  constructor(){
    super()
    this.state={
     
    }
  }
  render() {
    return (
      <Router>
        <div>
        <h2>App</h2>
        <ul>
          <li> <Link to="/home">Home</Link></li> 
          {/* 同樣 這兩個link讓他們轉(zhuǎn)移到Home中 我們的home組件就變成了下面的樣子 */}
        </ul>
        <Route path="/home" component={Home} >
         {/*<Route path="children1" component={Children} />*/} 
         {/*<Route path="children2" component={ChildrenTwo} />*/} 
          {/*先把這里注釋掉 然后我們來到Home組件內(nèi)*/}
        </Route>
      
        </div>
      </Router>
    )
  }
}

// home內(nèi)部用{this.props.match.url+子路由路徑}來獲取當(dāng)前的路徑并且加上我們要路由到的位置來進行路由匹配和路徑跳轉(zhuǎn)匹配 這樣書寫 Children和ChildrenTwo就是home的子路由了
class Home extends Component{
  constructor(){
    super()
  }
  
  render(){
    return(
      <div>
      <h2>我是Home</h2>
      <li><Link to={`${this.props.match.url}/children1`}>children1</Link></li>
      <li><Link to={`${this.props.match.url}/children2`}>children2</Link></li>
      <Route path={`${this.props.match.url}/children1`} component={Children} />
      <Route path={`${this.props.match.url}/children2`} component={ChildrenTwo} />   
      </div>
    )
  }
}

路由跳轉(zhuǎn)

聲明式跳轉(zhuǎn)上面已經(jīng)說過了 Link和NavLink 兩個標(biāo)簽就可以滿足了 我們主要說一下js跳轉(zhuǎn)

在4.0剛剛發(fā)布的時候 this.props.history.push('路徑')這個方法已經(jīng)行不通了,不過值得慶幸的是,我現(xiàn)在所使用的4.3.1版本又可以使用這個方法來進行js路由跳轉(zhuǎn)了。

我們用home組件來舉個例子

class Home extends Component{
  constructor(){
    super()
  }
  toPath=(home)=>{
    console.log(123)
    this.props.history.push({ //我們把要傳參的東西都放在push對象內(nèi)了
      pathname:home,  //我們要到達哪個路由
      search:"?a=1",  //明文傳參的模式
      query:{'type':'type'}, //query對象傳參
      state:{     //state對象傳參
        b:456
      }
    })
  // this.props.history.push('/123')
  }
  render(){
    return(
      <div>
      <h2 onClick={()=>{this.toPath(`${this.props.match.url}/children1/123`)}}>我是Home</h2>
      <li><Link to={`${this.props.match.url}/children1`}>children1</Link></li>
      <li><Link to={`${this.props.match.url}/children2`}>children2</Link></li>
      <Route path={`${this.props.match.url}/children1/:id`} component={Children} />
      <Route path={`${this.props.match.url}/children2`} component={ChildrenTwo} />   
      </div>
    )
  }
}

/*相應(yīng)的 我們在Children 組件里面有對應(yīng)的方法來獲取參數(shù)。*/

class Children extends Component{
  constructor(){
    super()
    this.state={
      
    }
  }
  render(){
    console.log(this.props.match.params.id) //這種是通過路徑上面的:id傳過來的參數(shù)
    console.log(this.props.location.query) //這是通過push的參數(shù)對象中的query傳過來的 和vue的query有區(qū)別 它不在地址欄 刷新丟失
    console.log(this.props.location.state) //這是通過push的參數(shù)對象中的state傳過來的 它不在地址欄 刷新丟失
    console.log(this.props.location.search) //暴露在地址欄,需要自行處理獲取數(shù)據(jù)


    return(
      <div>
        <h2>我是子組件1 </h2>
      </div>
    )
  }
}

總結(jié)

這一期我們主要還是講了react-router4.x的基礎(chǔ)使用和傳參方法,react-router4.x坑比較多,不過使用熟練了會讓你感覺很爽,大家不要吝嗇自己的時間多多學(xué)習(xí)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI