React路由6.0

Posted 一杯清泉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React路由6.0相关的知识,希望对你有一定的参考价值。

上次介绍了react路由5.0的一些用法,这次介绍最新的路由6.0用法,相比5.0变化还不少。

        路由5.0:https://blog.csdn.net/yoonerloop/article/details/124070341

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    document.getElementById('root')
);

一、Route、Routes

        实现路由的定义,Route需要使用Routes进行包裹,不能单独使用,能够智能的匹配,自动实现类似5.0的Switch的功能:        

<Routes>
    <Route path='/about' element=<About/>/>
</Routes>

二、Navigate

        用于实现页面的跳转,可以替代Redirect,例如下面首次进如页面,默认打开about 页面,这是需要使用Navigate,通过to指定要默认打开的页面:

<Routes>
    <Route path='/about' element=<About/>/>
    <Route path='/home' element=<Home/>/>
    <Route path='/home' element=<Demo/>/>
    <Route path='/' element=<Navigate to='/about'/>/>
</Routes>

        还可以实现自动的跳转,例如点击按钮每次+1当达到4的时候自动跳转:

<div>
    <h2>我是当前Home的内容</h2>
    sum === 4 ? <Navigate to='/about' replace=false/> : <h3>当前sum的值是:sum</h3>
    <button onClick=() => setSun(prevState => prevState + 1)>点我+1</button>
</div>

        默认replace是false,即push的形式,可以省略不写。

三、路由点击时候的默认效果

<NavLink className=(isActive) => 
    console.log(isActive)
 to='/home'>Home</NavLink>
<NavLink className=(isActive) => 
    console.log(isActive)
 to='/about'>About</NavLink>

        点击home时候className会被自动回调,传递isActive,如果当前路由被触发,传递true,否则是false,可以在这里处理样式。

四、useRoutes

        相当于对上面的内容的简化:

import React from 'react';
import BrowserRouter, NavLink, Router,Route, Routes, Navigate, useRoutes from "react-router-dom";
import About from "./components/about";
import Home from "./components/home";

/**
 * 路由6.0
 */
export default function App(props) 

    const element = useRoutes([
        
            path: '/home',
            element: <Home/>
        ,
        
            path: '/about',
            element: <About/>
        ,
        
            path: '/',
            element: <Navigate to='/about'/>
        
    ])

    return (
        <div>
            element
            <h4>内容</h4>
            <NavLink to='/home'>Home</NavLink>
            <NavLink to='/about'>About</NavLink>
        </div>
    );

        显示的效果和上面的一致。

        将路由单独抽取src/routes/index.js:

import Home from "../components/home";
import About from "../components/about";
import Navigate from "react-router-dom";
import React from "react";

export default [
    
        path: '/home',
        element: <Home/>
    ,
    
        path: '/about',
        element: <About/>
    ,
    
        path: '/',
        element: <Navigate to='/about'/>
    
]

        在App.js中只剩余:

import React from 'react';
import NavLink, useRoutes from "react-router-dom";
import routes from './routes'

export default function App() 

    const element = useRoutes(routes);

    return (
        <div>
            element
            <h4>内容</h4>
            <NavLink to='/home'>Home</NavLink>
            //end表示取消父级路由的高亮显示
            //<NavLink to='/about' end>About</NavLink>
            <NavLink to='/about'>About</NavLink>
        </div>
    );

五、嵌套路由


    path: '/about',
    element: <About/>,
    children: [
        
            path: 'hot',
            element: <Hot/>
        ,
        
            path: 'mine',
            element: <Mine/>
        
    ]
export default function About(props) 
    return (
        <div>
            <h2>About组件</h2>
            <ul>
                <li>
                    <NavLink to='hot'>热门</NavLink>
                </li>
                <li>
                    <NavLink to='mine'>我的</NavLink>
                </li>
            </ul>
            /*<h4>???</h4>*/
            /*指定路由组件位置*/
            <Outlet/>
        </div>
    );

注意:二级路由不需要斜杠,否则找不到。

六、Outlet

        用于占位,指定路由位置,例如上面的,点击hot或者mine,结果内容会显示在所在的位置,由于使用了路由表结构,如果不写,会显示不出来,同理,如下:

return (
    <div>
        <ul>
            
                message.map((m) => 
                    return (
                        <li key=m.id>
                            <Link to='message'>m.title</Link>
                        </li>
                    )
                )
            
        </ul>
        <Outlet/>
    </div>
);

        message的li会显示在  所在的位置,由于使用了路由表结构,不写这个也显示不出来。

七、路由传参Params--useParams

        在路由中使用params传递参数的时候时候。

(1)定义参数

export default [
    
        path: '/home',
        element: <Home/>
    ,
    
        path: '/about',
        element: <About/>,
        children: [
            
                path: 'hot',
                element: <Hot/>,
                children:[
                    
                        path: 'message/:id/:title/:content',
                        element: <Message/>
                    
                ]
            ,
            
                path: 'mine',
                element: <Mine/>
            
        ]
    ,
    
        path: '/',
        element: <Navigate to='/about'/>
    
]

(2)传递参数

<Link to=`message/$m.id/$m.title/$m.content`>m.title</Link>

(3)获取参数

export default function Message(props) 

    const params = useParams()
    //下面这种方式也能获取到,但是不常用
    const a = useMatch('/about/hot/message/:id/:title/:content')
    console.log(a)
    return (
       <div>
           <h4>消息列表</h4>
           <ul>
               <li>params.id</li>
               <li>params.title</li>
               <li>params.content</li>
           </ul>
       </div>
    );

八、路由传参search--useSearchParams

(1)定义参数

<Link to=`message?id=$m.id&title=$m.title&content=$m.content`>m.title</Link>

(2)获取参数

export default function Message(props) 

    //setSearch:更新收到的参数
    const [search, setSearch] = useSearchParams()
    const id = search.get('id');
    const title = search.get('title');
    const content = search.get('content');
    //不常用
    const x = useLocation();
    console.log(x)
    return (
        <div>
            <h4>消息列表</h4>
            <ul>
                <li>id</li>
                <li>title</li>
                <li>content</li>
            </ul>
        </div>
    );

九、路由传参state--useLocation

(1)定义参数

<Link to='message'
  state=
      id: m.id,
      title: m.title,
      content: m.content
  >m.title</Link>

(2)获取参数

export default function Message(props) 

    const state = useLocation();
    console.log(state)
    
    return (
        <div>
            <h4>消息列表</h4>
            <ul>
                <li>state.id</li>
                <li>state.title</li>
                <li>state.content</li>
            </ul>
        </div>
    );

十、页面跳转--非Link方式实现

        Link、NavLink自带点击实现页面跳转的效果,如果想要自定义实现点击效果,然后跳转,Link,NavLink就不行了,需要使用到useNavigate。

const navigate = useNavigate()

function showDetail(m) 
    console.log(8888)
    //视图切换
    navigate('message', 
        replace: false,
        state: 
            id: m.id,
            title: m.title,
            content: m.content
        
    )

        showDetail为点击某个按钮需要跳转的方法。对应路由5的this.props.history.push和replace模式,详情参考前面的。

十一、页面前进后退--useNavigate

        在路由5中使用withRouter实现全局页面的前进和后退功能,在路由6中统一使用useNavigate:

import React from 'react';
import useNavigate from "react-router-dom";

export default function Header(props) 

    const navigate = useNavigate()

    function back() 
        navigate(-1)
    

    function forward() 
        navigate(1)
    

    return (
        <div>
            <h2>头部</h2>
            <button onClick=forward>前进</button>
            <button onClick=back>后退</button>
        </div>
    );

十二、useInRouterContext

        判断上下文是否处于路由环境中,返回true表示在,false表示不在,凡是被BrowserRouter、HashRouter包裹的都处于路由环境中。

十三、useNavigationType

        判断当前页面是通过那种方式过来的。分为:push/replace/pop(刷新)。

十四、useOutlet

        用来呈现当组件中渲染的嵌套路由:

const a = useOutlet();
console.log('useOutlet', a)

        如果嵌套路由没生效a为null,如果已经挂载则展示路由对象。

四五、useResolvedPath

const x = useResolvedPath('/user/index.js?name=zhangsan&age=30')
console.log(x)

        解析路径时候使用,可以解析系统的,也可以解析自定义的,不常用。

以上是关于React路由6.0的主要内容,如果未能解决你的问题,请参考以下文章

使用react-router-dom@6,如何完成路由守卫这样的功能——使用高阶组件的包裹。

使用react-router-dom@6,如何完成路由守卫这样的功能——使用高阶组件的包裹。

react路由组件&&非路由组件

react函数式组件(非路由组件)实现路由跳转

React路由Route?

React12.路由