react路由(v5,v6版本)

902 阅读4分钟

react-router-dom(v5)

基本路由使用

import {HashRouter,Route} from 'react-router-dom'
function App() {
return (
<HashRouter>
  <Route path="/films" component={Films}></Route>
  <Route path="/cinemas"component={Cinemas} ></Route>
  <Route path="/center" component={Center}></Route>
  <Route path="/Home" render={()=>{return <Home></Home>}}></Route>
</HashRouter>
);
}

export default App;


function Films(){
return <div>Films</div>
}

function Cinemas(){
return <div>Cinemas</div>
}
function Center(){
return <div>Center</div>
}


function Home(){
return <div>Home</div>
}
Route中path属性是请求路径,component是匹配路径需要渲染的组件。

路由重定向

import {HashRouter,Route,Redirect} from 'react-router-dom'
function App() {
 return (
   <HashRouter>
     <Route path="/films" component={Films}></Route>
     <Route path="/cinemas"component={Cinemas} ></Route>
     <Route path="/center" component={Center}></Route>
     <Redirect from ='/' to="/films"></Redirect>
   </HashRouter>
 );
}

Redirect组件是重定向组件,当路由匹配from,会将路由重定向到to所代表的路由。

Switch(只渲染第一个匹配的路由)

import {HashRouter,Route,Redirect,Switch} from 'react-router-dom'
function App() {
return (
<HashRouter>
  <Switch>
    <Route path="/films" component={Films}></Route>
    <Route path="/cinemas"component={Cinemas} ></Route>
    <Route path="/center" component={Center}></Route>
    <Redirect from ='' to="/films"></Redirect>
  </Switch>
</HashRouter>
);
}

exact(精确路由匹配)

 <Route exact path="/cinemas"component={Cinemas} ></Route>

路由没有被exact标识的时候,可以匹配很多路径 如/cinemas/a,/cinemas/b/c,但是使用exact标识的时候只能被路由器/cinemas匹配,这就是精确匹配的作用。

路由匹配可能会匹配多个路由,而最终只会渲染最后一个组件,如果路由被Switch包裹,则会渲染第一个可匹配的组件,后续路由不再进行匹配。

嵌套路由


import {HashRouter,Route,Switch} from 'react-router-dom'
function App() {
return (
<HashRouter>
    <Route path="/films" component={Films}></Route>
</HashRouter>
);
}

export default App;


function Films(){
return <div>
   <Switch>
       <Route path="/films/person" component={Person}></Route>
       <Route path="/films/dog" component={Dog}></Route>
       <Route path="/films/cat" component={Cat}></Route>
   </Switch>
</div>
}

function Person(){
return <div>Person</div>
}

function Dog(){
return <div>Dog</div>
}
function Cat(){
return <div>Cat</div>
}

Films是一级路由匹配的组件, 一级路由组件内可以定义二级路由,从而使二级路由的组件可以渲染在一级路由组件内。

路由导航

1,声明式导航

import {NavLink} from 'react-router-dom'
  <NavLink to='/films'>电影</NavLink>
  <NavLink to='/cinemas'>影院</NavLink>
  <NavLink to='/center'>个人中心</NavLink>

NavLink是一个路由链接,当点击的时候会去匹配具体的路由 注意,NavLink只能包含在router组件内使用 2,编程式导航(props.history)

props.history.push('/films')

被Route路由包裹的组件内的props拥有history,location等参数。

3,编程式导航(hook useHistory跳转)

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

const history = useHistory();
history.push('/films')

路由传参

1,声明式导航传参 动态路由定义:

<Route path="/films/:id" component={Films}></Route>

组件接收路由参数:

props.match.params.id

2,编程式动态路由获取参数

props.history.push({
 pathname:'/films',query:{day:"friday}
})

获取参数:

props.location.query.day;

3,编程式动态路由获取参数

  props.history.push({
    pathname:'/films',state:{day:"friday}
  })

获取参数

 props.match.state.day;

路由模式

react-router-dom默认路由模式是hash模式,这种请求路径会带有一个#,改变为browser模式如下:

import {BrowserRouter,Route} from 'react-router-dom'
function App() {
return (
 <BrowserRouter>
   <Route path="/films" component={Films}></Route>
   <Route path="/cinemas"component={Cinemas} ></Route>
   <Route path="/center" component={Center}></Route>
 </BrowserRouter>
);
}

注意,Browser模式会真正的向后台发起请求,当请求页面不存在的时候,可能会报错,解决方法,后台需要进行处理,重新渲染前端页面

withRouter

import {withRouter} from 'react-router-dom'
withRouter(MyComponent)

MyComponent组件一旦被withRouter包裹,无论MyComponent组件是不是路由组件,都能够在内部porps中获取对应的history等路由信息。

react-router-dom(v6)

基本使用:


import {HashRouter as Router,Route,Routes,Link} from 'react-router-dom'
function App() {
return (
 <Router>
   <Link to="/person">人类</Link>
   <Link to="/dog"></Link>
   <Link to="/cat"></Link>
   <Routes>
     <Route path="/person"  element ={<Person/>}></Route>
     <Route path="/dog"  element ={<Dog/>}></Route>
     <Route path="/cat"  element ={<Cat/>}></Route>
   </Routes>
 </Router>
);
}

export default App;

function Person(){
return <div>Person</div>
}

function Dog(){
return <div>Dog</div>
}
function Cat(){
return <div>Cat</div>
}
  • 与版本5不同的一点是,v6版本的Route必须用Routes包裹,v6中的Routes代替了v5版本的switch.
  • v5的路由组件使用component和render属性引入,然而v6使用element属性

嵌套路由

一级路由:

 <Route path="/person"  element ={<Person/>}>
   <Route path="women"  element ={<Women/>}></Route>
   <Route path="man"  element ={<Man/>}></Route>
 </Route>

Person组件:

function Person(){
   return (
      <div>
         person
         <Outlet></Outlet>
      </div>
   )
}

v5版本的嵌套路由是将嵌套的路由写在组件内部,v6中的使嵌套路由更简单,Outlet是子路由组件的一个占位,此组件的匹配的子路由组件会显示在<Outlet></Outlet>位置上。

路由index作用

<Route path="/person" index element ={<Person/>}></Route>

近匹配父路由时,会显示当前组件。 index匹配当前

路由重定向

Navigate组件进行路由导航

<Route path="/dog"  element ={<Navigate to="/o/>}></Route>

也可以使用useNavigate hook自定义重定向路由组件:

export default function Redirect(props){
  const navigate = useNavigate();
  useEffect(()=>{
     navigate(props.to,{replace:true});
  },[])
  return;
}

v6中移除了v5的重定向组件

路由导航

1,声明式导航

1:Link
   <Link to="/person">人类</Link>
   <Link to="/dog">狗</Link>
   <Link to="/cat">猫</Link>
2:NavLink
   <NavLink to="person" className ={({isActive}) => isActive ? 'myclassName' : ''}>        </NavLink>
   
   

v6移除了的activeClassNameactiveStyle,而是使用className获取isActive来处理高亮显示效果。v6新增了组件也可做导航组件。 2,编程式导航

import {useNavigate} from 'react-router-dom';
const to = useNavigate();

to('/list',{state:data});

v5使用useHistory进行跳转,v6使用useNavigate代替了v5的useHistory。

获取路由参数

1,路由穿参:
路由定义

<Route path="/person/:id"  element ={<Person/>}></Route>
 路由参数获取(通过useParams获取):
import {useParams} from 'react-router-dom';
 function Person(){
   const params = useParams();
   return <div>{params.id}</div>
}

2:query穿参:

路由定义:

const navigate = useNavigate();
navigate('/preson?id=1');

获取参数(通过useSearchParams获取):

import {useSearchParams} from 'react-router-dom';
function Person(){
   const [searchParams,setSearchParams] = useSearchParams();
   return <div>{searchParams.get("id")}</div>
}

withRouter的替代

v6中删除了withRouter,而是使用useNavigate代替其功能的实现。如果是类组件,可以自己使用useNavigate封装成一个withRouter组件,从而在类组件中使用类似withRouter的功能。

useLocation

这个hook可以获取对应的路由信息。v5中的location中的信息是在history中获取的。

路由懒加载

懒加载组件封装:

const lazyLoad = (path) => {
  const Comp = React.lazy(()=>import('/${path}'));
  return (
     <React.Suspense fallback = {<>加载中。。。</>}>
         <Comp />
     </React.Suspense>
  )
}

路由中使用

<Route path="man"  element ={lazyLoad('Person')}></Route>

useRoutes

v6中的useRoutes代替react-router-config

  const routes = useRoutes([
    {
      path:'/person',
      element: <Person/>,
      children:[ 
       {
          path:'/women',
          element: <Women/>,
       },
       {
          path:'/man',
          element: <Man/>,
       }
      
      ]
    },
    {
       path:'/cat',
       element: <Cat/>,
    },
    {
       path:'/dog',
       element: <Dog/>
    }
  ])