React RouterV5.1

122 阅读1分钟

1、升级V5.1指南

  • <Route children> 替换掉 <Route render> 和/或 <Route component>
  • 使用下面的hook 访问路由器状态,如当前位置和参数
  • 用下面hook替换 withRouter 的所有用途
  • 用 useRouteMatch 替换不在 <Switch> 内的 <Route>,或将它们包装在 <Switch>
  • 移除了<Switch>里面的的<Redirect>原因主要是不利于SEO,客户端重定向可以在Route的render里做
<Switch>
     <Route path="about" render={() => <Redirect to="about-us" />} />
</Switch>

2、hooks

2.1 UseParams

V5.1之前的两种方式

import React from 'react'
import ReactDOM from 'react-dom'
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'

// BlogPost 接受一个 match prop,获取url参数
function BlogPost({ match }) {
  let { slug } = match.params
  // ...
}

ReactDOM.render(
  <Router>
    <div>
      <Switch>
        {/* 使用component prop */}
        <Route path="/blog/:slug" component={BlogPost} />

        {/* 使用 `render` prop */}
        <Route
          path="/posts/:slug"
          render={({ match }) => <BlogPost match={match} />}
        />
      </Switch>
    </div>
  </Router>,
  document.getElementById('root')
)

说明:props 是compoent的方式和 用render的方式都可以获取URL参数,但是component方式不支持自定义参数,而render的方式虽然支持自定义传参,但还是得手动把从回调拿到的值(match)传给自己的组件.

使用useParams

import React from 'react'
import ReactDOM from 'react-dom'
import {
  BrowserRouter as Router,
  Route,
  Switch,
  useParams
} from 'react-router-dom'

function BlogPost() {
  // We can call useParams() here to get the params,
  // or in any child element as well!
  let { slug } = useParams()
  // ...
}

ReactDOM.render(
  <Router>
    <div>
      <Switch>
        {/* No weird props here, just use
            regular `children` elements! */}
        <Route path="/posts/:slug">
          <BlogPost />
        </Route>
      </Switch>
    </div>
  </Router>,
  document.getElementById('root')
)

使用小结:直接把组件作为children,路由参数可以直接从hook--useParams里取,不用再记组件配合的特殊语法。

2.2 useLocation

返回一个location对象,一个监听页面变化的例子

import { Switch, useLocation } from 'react-router-dom'

function usePageViews() {
  let location = useLocation()

  useEffect(
    () => {
      ga.send(['pageview', location.pathname])
    },
    [location]
  )
}

function App() {
  usePageViews()
  return <Switch>{/* your routes here */}</Switch>
}

2.3 useHistory

返回history对象,

2.4 useRouteMatch

路由匹配hook,在外使用,比之前写法更简洁

// before
import { Route } from 'react-router-dom'

function App() {
  return (
    <div>
      {/* ... */}
      <Route
        path="/BLOG/:slug/"
        strict
        sensitive
        render={({ match }) => {
          return match ? <BlogPost match={match} /> : <NotFound />
        }}
      />
    </div>
  )
}

// after
import { useRouteMatch } from 'react-router-dom'

function App() {
  let match = useRouteMatch({
    path: '/BLOG/:slug/',
    strict: true,
    sensitive: true
  })

  return (
    <div>
      {/* ... */}
      {match ? <BlogPost match={match} /> : <NotFound />}
    </div>
  )
}

完。