五分鐘教你瞭解一下react路由知識
什麼是路由
簡單的說就是根據不同的地址,web服務器處理不同的業務以及邏輯。
以下代碼全部運行在react腳手架中
純組件的基本使用
// 組件更新機制: // 隻要父組件重新渲染瞭, 所有的組件子樹, 也會更新 // 性能優化 // 1. 減輕state // 2. 避免不必要的重新渲染 (性能優化) // shouldComponentUpdate(nextProps, nextState) { .... } // 鉤子函數返回一個佈爾值, true要更新 false不更新 // 手動實現固然是可以的, 但是太麻煩 // 3. 實際官網提供瞭一個純組件, 內部已經幫你實現好瞭 shouldComponentUpdate 的邏輯 // 會幫你進行props 和 state的比對, 決定是否要更新 // 普通組件: class App extends React.Component // 純組件: class App extends React.PureComponent 會比普通組件, 多一個比對數據的過程 // 比如: 一個組件要渲染出來, 性能損耗很大, 此時可以考慮純組件, 避免掉一些無意義的更新 // 不是所有的場景, 都要用純組件, 正常應該都用普通組件 import React from 'react' import ReactDOM from 'react-dom' class App extends React.PureComponent { state = { nameList: ['帥鵬', '呂佈', '張飛'], currentName: '', } render() { console.log('App-render') return ( <div> <h1>我是App組件</h1> <h3>結果: {this.state.currentName}</h3> <button onClick={this.handleClick.bind(this)}>點名</button> </div> ) } handleClick() { const randomIndex = parseInt(Math.random() * this.state.nameList.length) const currentName = this.state.nameList[randomIndex] this.setState({ currentName, }) console.log(currentName) } // 需求: 如果state的值, 沒有發生變化, 其實也不需要更新, 避免一些不必要的更新 // shouldComponentUpdate(nextProps, nextState) { // if (this.state.currentName === nextState.currentName) { // return false // } else { // return true // } // } } ReactDOM.render(<App></App>, document.getElementById('root'))
純組件使用的註意點
// 4. 純組件的使用註意點 (如果純組件有子組件, 子組件也要是純組件 (一傢子都純)) // (1) 純組件內部進行的是淺層對比, 值類型沒有問題, 復雜類型隻比較地址 // (2) 使用純組件, 更新數據時, 簡單類型沒有問題, 復雜類型更新瞭, 是需要修改地址的(新對象 / 新數組) import React from 'react' import ReactDOM from 'react-dom' class App extends React.PureComponent { state = { nameList: ['帥鵬', '呂佈', '張飛'], currentName: '', obj: { name: 'zs', age: 18, }, } render() { console.log('App-render') return ( <div> <h1>我是App組件</h1> <p>name: {this.state.obj.name}</p> <p>{this.state.nameList}</p> <button onClick={this.handleClick.bind(this)}>改值</button> </div> ) } handleClick() { // 要更新對象, 要準備一個新對象 // const obj = { ...this.state.obj } // obj.name = 'ls' // this.setState({ // obj: obj, // }) // 要更新數組, 要準備一個新數組 // this.setState({ // nameList: [...this.state.nameList, '王五'], // }) const arr = [...this.state.nameList] arr.push('王五') this.setState({ nameList: arr, }) } } ReactDOM.render(<App></App>, document.getElementById('root'))
路由的基本初體驗
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter, Link, Route } from 'react-router-dom' // 路由的使用: // 1. 下載 yarn add react-router-dom // 2. react-router-dom是一個包, 包含瞭很多的組件 // 3. HashRouter組件, 是整個的路由對象, 一個項目就一個, 需要將整個項目的內容包裹 // 4. Link組件, 渲染成一個 a 鏈接, 可以用於路由跳轉, 通過 to 配置路徑 // 5. Route組件, 配置路由規則(哪個路徑匹配哪個組件), 也是路由出口! // 每個Route互相之間是獨立的, 隻要路徑匹配, 就可以展示配置的組件 // 定義瞭三個函數組件 const Home = () => <div>我是Home組件</div> const Login = () => <div>我是Login組件</div> const User = () => <div>我是User組件</div> class App extends React.PureComponent { render() { return ( <div> <h1>我是App組件</h1> <ul> <li> <Link to="/home">首頁</Link> </li> <li> <Link to="/login">登錄</Link> </li> <li> <Link to="/user">用戶</Link> </li> </ul> {/* 隻要path路徑, 和地址欄的路徑匹配, 就會展示配置的組件 */} <Route path="/home" component={Home}></Route> <Route path="/login" component={Login}></Route> <Route path="/user" component={User}></Route> </div> ) } } ReactDOM.render( <HashRouter> <App></App> </HashRouter>, document.getElementById('root') )
HashRouter和BrowserRouter
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter as Router, Link, Route } from 'react-router-dom' // Router組件, 有兩種 HashRouter, BrowserRouter // 1. HashRouter底層實現基於: 地址欄的hash值, 基於錨點跳轉實現的 // 2. BrowserRouter底層實現基於: h5 的 history API, 地址欄沒有 # // (如果要用開發時, 沒有問題, 但是上線瞭, 是需要後臺配置的) // 定義瞭三個函數組件 const Home = () => <div>我是Home組件</div> const Login = () => <div>我是Login組件</div> const User = () => <div>我是User組件</div> class App extends React.PureComponent { render() { return ( <div> <h1>我是App組件</h1> <ul> <li> <Link to="/home">首頁</Link> </li> <li> <Link to="/login">登錄</Link> </li> <li> <Link to="/user">用戶</Link> </li> </ul> {/* 隻要path路徑, 和地址欄的路徑匹配, 就會展示配置的組件 */} <Route path="/home" component={Home}></Route> <Route path="/login" component={Login}></Route> <Route path="/user" component={User}></Route> </div> ) } } ReactDOM.render( <Router> <App></App> </Router>, document.getElementById('root') )
Link組件和NavLink組件
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter as Router, NavLink, Route } from 'react-router-dom' import './index.css' // Link組件 和 NavLink組件 // 1. Link組件, 渲染成a鏈接, 用於路由跳轉, 通過to配置路徑 // 默認的Link, 不會有高亮的類名標識 // 2. NavLink組件, 渲染成a鏈接, 用於路由跳轉, 通過to配置路徑 // (1) NavLink, 在路徑匹配時, 會有高亮的類名 active // (2) 可以通過activeClassName, 配置高亮的類名 // (3) 可以通過activeStyle, 直接配置改標簽, 高亮的樣式 // (4) 進行的是模糊匹配 to="/home" 可以匹配 /home /home/aa // 精確匹配, 需要配置 exact 屬性, to="/home", 隻能匹配 /home, 隻會在 /home 時高亮 // 定義瞭三個函數組件 const Home = () => <div>我是Home組件</div> const Login = () => <div>我是Login組件</div> const User = () => <div>我是User組件</div> class App extends React.PureComponent { render() { return ( <div> <h1>我是App組件</h1> <ul> <li> <NavLink exact to="/" activeStyle={{ color: 'red', fontSize: '30px' }} > 首頁 </NavLink> </li> <li> <NavLink to="/login" activeClassName="selected"> 登錄 </NavLink> </li> <li> <NavLink to="/user" activeClassName="selected"> 用戶 </NavLink> </li> </ul> {/* 隻要path路徑, 和地址欄的路徑匹配, 就會展示配置的組件 */} <Route path="/home" component={Home}></Route> <Route path="/login" component={Login}></Route> <Route path="/user" component={User}></Route> </div> ) } } ReactDOM.render( <Router> <App></App> </Router>, document.getElementById('root') )
/**index.css*/ .active { color: red; font-size: 30px; } .selected { color: blue; font-size: 30px; }
Route和Switch組件
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter as Router, NavLink, Route, Switch } from 'react-router-dom' import './index.css' // Route組件 // 作用: 可以配置路由規則, 也是路由的出口, 隻要路徑匹配瞭, 那麼配置的組件, 就會在這裡展示 // <Route path="/login" component={Login}></Route> // 1. 每個Route之間, 互相是獨立的 (包括配置多個相同路徑, 顯示不同組件, 也是可以的) // 2. Route配置的路徑, 也是進行的模糊匹配, 可以通過 exact 進行精確匹配 // 3. 如果不配置路徑, 那麼配置的組件, 默認都會展示 // 會配合Switch組件, 可以完成404頁面的配置 // Switch組件: 可以將多個Route組件包裹, 可以讓第一個匹配的Route組件展示, 後續的不管 // 定義瞭函數組件 const Home = () => <div>我是Home組件</div> const Login = () => <div>我是Login組件</div> const User = () => <div>我是User組件</div> const Error = () => <div>我是404頁面, 您要訪問的頁面不存在!!!</div> class App extends React.PureComponent { render() { return ( <div> <h1>我是App組件</h1> <ul> <li> <NavLink exact to="/" activeStyle={{ color: 'red', fontSize: '30px' }} > 首頁 </NavLink> </li> <li> <NavLink to="/login" activeClassName="selected"> 登錄 </NavLink> </li> <li> <NavLink to="/user" activeClassName="selected"> 用戶 </NavLink> </li> </ul> {/* 隻要path路徑, 和地址欄的路徑匹配, 就會展示配置的組件 */} <Switch> <Route path="/" component={Home} exact></Route> <Route path="/login" component={Login}></Route> <Route path="/user" component={User}></Route> <Route component={Error}></Route> </Switch> </div> ) } } ReactDOM.render( <Router> <App></App> </Router>, document.getElementById('root') )
嵌套路由
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter as Router, NavLink, Route, Switch, Redirect, } from 'react-router-dom' import './index.css' // Redirect組件: 可以重定向, from從哪 to跳到哪 // react中, 配置嵌套路由, 非常的簡單, 你隻需要在需要寫嵌套子路由的地方, 直接寫Route組件即可 // 前提條件, 你配置的嵌套子路由, 路徑一定要包含父路由的路徑 // 定義瞭函數組件 const Home = () => ( <div> <h3>我是Home組件</h3> </div> ) const Login = () => ( <div> <h3>我是Login組件</h3> </div> ) // ------------------------------------------------------------------------ // 需求: 用戶User組件內部, 還有個人信息, 我的收藏 const User = () => ( <div> <h3>我是User組件</h3> <Route path="/user" exact component={UserDefault}></Route> <Route path="/user/info" component={Info}></Route> <Route path="/user/star" component={Star}></Route> </div> ) const UserDefault = () => <div>我是默認的User內容</div> const Info = () => <div>我是Info組件</div> const Star = () => <div>我是Star組件</div> // ------------------------------------------------------------------------- const Error = () => <div>我是404頁面, 您要訪問的頁面不存在!!!</div> class App extends React.PureComponent { render() { return ( <div> <h1>我是App組件</h1> <ul> <li> <NavLink exact to="/" activeStyle={{ color: 'red', fontSize: '30px' }} > 首頁 </NavLink> </li> <li> <NavLink to="/login" activeClassName="selected"> 登錄 </NavLink> </li> <li> <NavLink to="/user" activeClassName="selected"> 用戶 </NavLink> </li> </ul> {/* 隻要path路徑, 和地址欄的路徑匹配, 就會展示配置的組件 */} <Switch> <Route path="/" component={Home} exact></Route> <Redirect from="/home" to="/"></Redirect> <Route path="/login" component={Login}></Route> <Route path="/user" component={User}></Route> <Route component={Error}></Route> </Switch> </div> ) } } ReactDOM.render( <Router> <App></App> </Router>, document.getElementById('root') )
路由傳參
import React from 'react' import ReactDOM from 'react-dom' import { HashRouter as Router, Route, Link } from 'react-router-dom' import './index.css' // 如果想拿到動態路由的參數信息, 需要通過props獲取, // Route會將路由相關信息, 相關方法, 都會通過 props 傳給你的組件 // const Product = (props) => <div>我是product組件</div> class Product extends React.Component { render() { // this.props 參數 // (1) history 裡面存放的是跳轉路由的方法 // (2) location 裡面存放的是當前路由地址 // (3) match 裡面存放的是動態路由參數 console.log(this.props) console.log(this.props.match.params.id) return ( <div> <h3>我是product組件 - {this.props.match.params.id}</h3> <button onClick={this.handleClick.bind(this)}>回首頁</button> </div> ) } handleClick() { // console.log(this.props.history) // this.props.history.go(-1) this.props.history.push('/home') } } const Home = () => <div>我是首頁</div> class App extends React.Component { render() { return ( <div> <h1>我是App組件</h1> <div> <Link to="/home">首頁</Link> <Link to="/product/1">商品1</Link> <Link to="/product/2">商品2</Link> <Link to="/product/3">商品3</Link> <Link to="/product/4">商品4</Link> </div> <Route path="/product/:id" component={Product}></Route> <Route path="/home" component={Home}></Route> </div> ) } } ReactDOM.render( <Router> <App></App> </Router>, document.getElementById('root') )
到此這篇關於五分鐘教你瞭解一下react路由知識的文章就介紹到這瞭,更多相關react路由內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- React-Router6版本的更新引起的路由用法變化
- react實現移動端二級路由嵌套詳解
- React中路由參數如何改變頁面不刷新數據的情況
- React中react-redux和路由詳解
- react路由守衛的實現(路由攔截)