面試官我想作個Reacter(React路由)

路由的基礎用法回顧, 源碼study,文章首發於 docs,求個star

依賴

路由依賴於 react-router ,可是通常 pc 路由使用 react-router-dom ,它依賴於 react-routerjavascript

npm i react-router-dom -S

基本路由

  • Link 組件渲染路徑,形式 a 標籤
  • Route 組件渲染組件,匹配路由
  • HashRouter 是 hash 路由,BrowserRouter 是 history 路由
  • component 和 render 均可以渲染組件,component 優先級匹配高於 render;render 爲一個函數,能夠作邏輯渲染,給組件傳遞參數
import { HashRouter, Route, Link } from 'react-router-dom'
class App extends Component {
  ...
  render() {
    return (
      <div>
        <Link to="/" >首頁</Link>
        <Link to="/page">Page</Link>
   {/* 配置路由規則  exact表示精確匹配,防止匹配其餘頁面的時候匹配到/,也就是首頁*/}
        <Route path="/" exact component={Home}></Route>
        <Route path="/page" component={Page}></Route>
        <Route
          path={`/user/login`}
          render={routeProps => {
            return (
              <List name="這是render渲染" user="mondo" {...routeProps} />
            );
          }}
        ></Route>
      </div>
    );
  }
}

ReactDOM.render(
  <HashRouter>
    <App/>
  </HashRouter>, 
  document.getElementById('root')
)
  • Link 只配置路由,NavLink 可作導航路由,可配置activeClassNameactiveStyle
import { NavLink as Link } from 'react-router-dom';

class Nav extends Component {
  render () {
    return (
      <ul className="nav">
        <li className="list"><NavLink to="/archive" activeClassName='active'>歸檔</NavLink></li>
        <li className="list"><NavLink to="/about" activeClassName='active'>關於</NavLink></li>
      </ul>
    );
  };
}

export default Nav;

嵌套路由

在想要嵌套的組件裏再次配置路由java

// User.js
import React from 'react'
import { Route, Link } from 'react-router-dom'

const User = (props) => {
      // match 能夠讀取上層路由
    const { match } = props
    return (
       <div>
            <Link to={`${match.path}/login`}>登陸</Link>
            <Link to="/user/reg">註冊</Link>
            <Route path={`${match.path}/login`}>login</Route>
            <Route path="/user/reg">reg</Route>
       </div>
    )
}

export default User

// App.js
<Route path="/user" component={User}></Route>

路由傳值

  • params 動態路由傳參,經過組件內 props.match.params 訪問
// App.js
<Link to="/list/1/4">列表</Link>
{/* 必須使用 component 來指定組件,否則訪問不到match */}
<Route path="/list/:id/:user" component={List}/>

// List.js
const List = (props) => {
  console.log(props.match.params) // { id: 1, user: 4 } 
  return (
    <h2>
      { props.name }{ props.children }
    </h2>
  )
}
  • query 傳值直接取 ? 後面的值,可是 router 沒提供相應的方法,須要本身寫一個函數來提取參數
  • 隱式傳參,使用 to 傳遞對象 state

編程式路由

利用 props.history 來跳轉路由react

// List.js
const { history } = props

const goRoute = () => {
  if (history) {
    history..push('/user')
  }
}
// 能夠使用對象傳值
const goRoute = () => {
  if (history) {
    history..push({
        pathname: '/user',
        state: {
            id: 2
        }
    })
  }
}

重定向

重定向使用 Switch 組件git

// ErrorPage.js
import React from 'react'

class Error extends React.Component{
    render(){
        return(
            <h1>頁面404</h1>
        )
    }
}
export default Error

// App.js
import ErrorPage from './components/ErrorPage'

class App extends React.Component {
  ...
  render() {
    ...
    {/* Switch表示若是匹配到了路由,就再也不往下面匹配了,若是不寫Switch,則一直會匹配到404頁面 */}
    <Switch>
      {/* 配置路由規則  exact表示精確匹配,防止匹配其餘頁面的時候匹配到/,也就是首頁*/}
      <Route path="/home" exact>Home</Route>
      <Route path="/page" component={Page}></Route>
      <Route path="/user" component={User}></Route>
      {/* 必須使用 component 來指定組件,否則訪問不到match */}
      <Route path="/list/:id/:user" component={List}></Route>
      <Redirect from="/" to="/home" exact></Redirect>
      {/* 沒有寫path表示匹配到全部的路徑 */}
      <Route component={ErrorPage} />
    </Switch>
  }
}

withRouter

因爲只有 Route 包裹的組件才能夠訪問到 props 內部的路由信息,能夠引入 withRouter 高階組件來使內部組件也能夠訪問路由信息github

import React from 'react'

import { withRouter } from 'react-router-dom'


const GoBack = props => {
  console.log(props)
  const goBack = () => {
    props.history.go(-1)
  }
  return <button onClick={goBack}>返回</button>
}

export default withRouter(GoBack)
相關文章
相關標籤/搜索