称泥 發表於 2023-3-1 12:55:00

关于React-Router6 (React 路由)

<h1>一、概要</h1>
<div>
<p>(1)每个单页应用其实是一系列的 JS 文件,当用户请求网站时,网站返回一整个(或一系列)的 js 文件和 HTML,而当用户在某个页面内点击时,你需要告诉浏览器怎么加载另一个页面地址。单页应用中通常只有一个&nbsp;<code>index.html</code>&nbsp;文件的,所以浏览器自带的&nbsp;<code>&lt;a&gt;</code>&nbsp;链接 tag 并不能用来做单页应用的跳转,因此你需要一个在 React 中的路由实现。</p>
<p>然而 React 框架本身是不带路由功能的,因此如果你需要实现路由功能让用户可以在多个单页应用中跳转的话,就需要使用 React-Router。</p>
<p>&nbsp;</p>
<p>(2)全局路由有常用两种路由模式可选:<span style="color: rgba(128, 128, 0, 1)"><strong>HashRouter 和 BrowserRouter</strong></span></p>
<ul>
<li>
<p>HashRouter:URL中采用的是hash(#)部分去创建路由,类似www.example.com/#/</p>
</li>
<li>
<p>BrowserRouter:URL采用真实的URL资源 这里我们采用BrowserRouter来创建路由</p>
</li>
</ul>
<h2>1.1、route的功能</h2>
<p><img src="https://img2023.cnblogs.com/blog/2762061/202303/2762061-20230301125810953-1083466018.png" alt="" loading="lazy"></p>
<h2>1.2、路由通配符</h2>
<div class="cnblogs_code">
<pre>/groups

/groups/<span style="color: rgba(0, 0, 0, 1)">admin

</span>/users/<span style="color: rgba(0, 0, 0, 1)">:id

</span>/users/:id/messages

/files/* /files/:id<span style="color: rgba(0, 128, 0, 1)">/*</span></pre>
</div>
<p>&nbsp;</p>
</div>
<h1>二、使用</h1>
<h2>&nbsp;2.1、安装&nbsp;React-Router</h2>
<div class="cnblogs_code">
<pre>npm install react-router-dom(没有指定版本,默认最新版)</pre>
</div>
<h2>2.2、创建组件</h2>
<p>在 src 文件夹里面创建一个 component / index / index.jsx 组件,在 index 文件夹里再创建3个孙组件( index / p1.jsx、index / p2.jsx、index / p3.jsx)</p>
<p>在component文件夹下,再创建一个user文件夹,里面放3个孙组件(user / u1.jsx、user / u2.jsx、user / u3.jsx)</p>
<p>以上,创建那么文件夹和文件的作用是为了方便测试而已,要使用的时候还是按照自己的实际需要好!!!</p>
<h2>2.3、孙组件内容</h2>
<p><strong><span style="color: rgba(128, 128, 0, 1)">p1.jsx代码如下:</span></strong></p>
<div class="cnblogs_code">
<pre>import React from "react"<span style="color: rgba(0, 0, 0, 1)">;

export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class Pone extends React.Component{
    render(){
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">(
            </span>&lt;&gt;
                &lt;h1&gt;p1&lt;/h1&gt;
            &lt;/&gt;
<span style="color: rgba(0, 0, 0, 1)">      )
    }
}</span></pre>
</div>
<p><strong><span style="color: rgba(255, 0, 0, 1)">其他几个孙组件的内容大致一样就不展示了!</span></strong></p>
<h2>2.4、子组件内容</h2>
<p><strong><span style="color: rgba(128, 128, 0, 1)">index.jsx 代码如下:</span></strong></p>
<div class="cnblogs_code">
<pre>import React from "react"<span style="color: rgba(0, 0, 0, 1)">;
import { NavLink,Outlet } from </span>"react-router-dom"<span style="color: rgba(0, 0, 0, 1)">;

export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> class Index extends React.Component{
    render(){
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">(
            </span>&lt;&gt;<span style="color: rgba(0, 0, 0, 1)">
                {</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 跳转页面到某个路由 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
                </span>&lt;NavLink to="p1"&gt;p1&lt;/NavLink&gt;
                &lt;NavLink to="p2"&gt;p2&lt;/NavLink&gt;
                &lt;NavLink to="p3"&gt;p3&lt;/NavLink&gt;
                &lt;hr /&gt;
                {<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> 这个也是占位符,把子路由的内容放在这里 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">}
                </span>&lt;Outlet&gt;&lt;/Outlet&gt;
            &lt;/&gt;
<span style="color: rgba(0, 0, 0, 1)">      )
    }
}</span></pre>
</div>
<p><span style="color: rgba(255, 0, 0, 1)"><strong>其他几个子组件的内容大致一样就不展示了!</strong></span></p>
<h2>2.5、父组件内容</h2>
<p><strong><span style="color: rgba(128, 128, 0, 1)">App.js 代码如下:</span></strong></p>
<div class="cnblogs_code">
<pre>import route from "./route"<span style="color: rgba(0, 0, 0, 1)">;
import { NavLink,useRoutes } from </span>"react-router-dom"<span style="color: rgba(0, 0, 0, 1)">;
import </span>'./index.css'

<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> App() {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 占位符,相当于把路由放在这个地方</span>
const element =<span style="color: rgba(0, 0, 0, 1)"> useRoutes(route)
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
    </span>&lt;div className="App"&gt;
      &lt;NavLink to="/home"&gt;主页&lt;/NavLink&gt;
      &lt;NavLink to="/user"&gt;用户&lt;/NavLink&gt;
      &lt;hr /&gt;
<span style="color: rgba(0, 0, 0, 1)">      {
      element
      }
    </span>&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">);
}

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> App;</pre>
</div>
<h2>2.6、创建路由表</h2>
<p>在 src 文件夹下创建一个 route 文件夹下,在route文件夹下创建一个 index.js</p>
<p><strong><span style="color: rgba(128, 128, 0, 1)">具体代码如下:</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 组件</span>
import Index from "../component/index"<span style="color: rgba(0, 0, 0, 1)">;
import Pone from </span>"../component/index/p1"<span style="color: rgba(0, 0, 0, 1)">;
import Ptwo from </span>"../component/index/p2"<span style="color: rgba(0, 0, 0, 1)">;
import Pthere from </span>"../component/index/p3"<span style="color: rgba(0, 0, 0, 1)">;

import User from </span>"../component/user/user"<span style="color: rgba(0, 0, 0, 1)">;
import Uone from </span>"../component/user/u1"<span style="color: rgba(0, 0, 0, 1)">;
import Utwo from </span>"../component/user/u2"<span style="color: rgba(0, 0, 0, 1)">;
import Uthere from </span>"../component/user/u3"<span style="color: rgba(0, 0, 0, 1)">;
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 跳转页面的</span>
import { Navigate } from "react-router-dom"<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 默认导出</span><span style="color: rgba(0, 128, 0, 1)">
//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-next-line import/no-anonymous-default-export</span>
export <span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> [
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 路由规则</span>
<span style="color: rgba(0, 0, 0, 1)">    {
      path:</span>"/home"<span style="color: rgba(0, 0, 0, 1)">,
      element: </span>&lt;Index&gt;&lt;/Index&gt;,
      <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 一级路由的子路由,即嵌套路由</span>
<span style="color: rgba(0, 0, 0, 1)">      children: [
            {
                path: </span>"p1"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Pone&gt;&lt;/Pone&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path: </span>"p2"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Ptwo&gt;&lt;/Ptwo&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path: </span>"p3"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Pthere&gt;&lt;/Pthere&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path:</span>""<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Navigate to="/home/p1"&gt;&lt;/Navigate&gt;
<span style="color: rgba(0, 0, 0, 1)">            }
      ]
    },
    {
      path:</span>"/"<span style="color: rgba(0, 0, 0, 1)">,
      element: </span>&lt;Navigate to="/home"&gt;&lt;/Navigate&gt; //<span style="color: rgba(0, 0, 0, 1)"> Navigate:页面的跳转;此规则用于重定向
    },
    {
      path:</span>"/user"<span style="color: rgba(0, 0, 0, 1)">,
      element: </span>&lt;User&gt;&lt;/User&gt;,
<span style="color: rgba(0, 0, 0, 1)">      children:[
            {
                path: </span>"u1"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Uone&gt;&lt;/Uone&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path: </span>"u2"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Utwo&gt;&lt;/Utwo&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path: </span>"u3"<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Uthere&gt;&lt;/Uthere&gt;
<span style="color: rgba(0, 0, 0, 1)">            },
            {
                path:</span>""<span style="color: rgba(0, 0, 0, 1)">,
                element: </span>&lt;Navigate to="/user/u1"&gt;&lt;/Navigate&gt;
<span style="color: rgba(0, 0, 0, 1)">            }
      ]
    }

]</span></pre>
</div>
<h2>2.7、入口文件内容(src/index.js)</h2>
<div class="cnblogs_code">
<pre> import React from 'react'<span style="color: rgba(0, 0, 0, 1)">;
import ReactDOM from </span>'react-dom/client'<span style="color: rgba(0, 0, 0, 1)">;
import App from </span>'./App'<span style="color: rgba(0, 0, 0, 1)">;
import { BrowserRouter } from </span>'react-router-dom'<span style="color: rgba(0, 0, 0, 1)">;   

const root </span>= ReactDOM.createRoot(document.getElementById('root'<span style="color: rgba(0, 0, 0, 1)">));
root.render(
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> React.StrictMode:检测代码是否规范</span>
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &lt;React.StrictMode&gt; </span>
    &lt;BrowserRouter&gt;
      &lt;App /&gt;
    &lt;/BrowserRouter&gt;
<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> &lt;/React.StrictMode&gt;</span>
<span style="color: rgba(0, 0, 0, 1)">
);</span></pre>
</div>
<h2>2.8、运行结果</h2>
<p><img src="https://img2023.cnblogs.com/blog/2762061/202303/2762061-20230301115455292-1622410033.png" alt="" loading="lazy"></p>
<h1>三、跳转页面的方法</h1>
<h2>3.1、在路由表导入“ 注册 ” 的组件</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 该文件为路由表,定义一些路由信息</span>
<span style="color: rgba(0, 0, 255, 1)">import</span> { Navigate } from 'react-router-dom'
<span style="color: rgba(0, 0, 255, 1)">import</span> React,{lazy} from 'react'

<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 动态加载组件</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> Login = lazy(()=&gt;<span style="color: rgba(0, 0, 255, 1)">import</span>('../view/Login'<span style="color: rgba(0, 0, 0, 1)">))
</span><span style="color: rgba(0, 0, 255, 1)">const</span> Register = lazy(()=&gt;<span style="color: rgba(0, 0, 255, 1)">import</span>('../view/Register'<span style="color: rgba(0, 0, 0, 1)">))

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 解决懒加载报错问题</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> fun = (Com)=&gt;(&lt;React.Suspense fallback={'loading...'}&gt;<span style="color: rgba(0, 0, 0, 1)">
      {Com}
    </span>&lt;/React.Suspense&gt;<span style="color: rgba(0, 0, 0, 1)">
)

export </span><span style="color: rgba(0, 0, 255, 1)">default</span><span style="color: rgba(0, 0, 0, 1)"> [
    {
      path: </span>'/Login'<span style="color: rgba(0, 0, 0, 1)">,
      element: fun(</span>&lt;Login/&gt;)<span style="color: rgba(0, 0, 0, 1)">
    },
    {
      path: </span>'/Register'<span style="color: rgba(0, 0, 0, 1)">,
      element: fun(</span>&lt;Register/&gt;)<span style="color: rgba(0, 0, 0, 1)">
    },
    {
      path: </span>'/'<span style="color: rgba(0, 0, 0, 1)">,
      element: </span>&lt;Navigate to="/Login"/&gt;<span style="color: rgba(0, 0, 0, 1)">
    }
]</span></pre>
</div>
<h2>3.2、使用<code>useNavigate</code>从登录页面跳转到注册页面</h2>
<p><strong><span style="color: rgba(128, 128, 0, 1)">导入:</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span> { useNavigate } from 'react-router-dom';</pre>
</div>
<p><strong><span style="color: rgba(128, 128, 0, 1)">实现:</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">const</span> navigate =<span style="color: rgba(0, 0, 0, 1)"> useNavigate();
navigate(</span>'/path');</pre>
</div>
<p><strong><span style="color: rgba(255, 0, 0, 1)">报错:</span></strong></p>
<div class="cnblogs_code">
<pre>A component suspended <span style="color: rgba(0, 0, 255, 1)">while</span> responding to synchronous input. This will cause the UI to be replaced with a loading indicator. To fix, updates that suspend should be wrapped with startTransition.</pre>
</div>
<p><strong><span style="color: rgba(128, 128, 0, 1)">原因:</span></strong></p>
<p>在响应同步输入时,某个组件发生了挂起(suspended)的情况,导致用户界面被替换为加载指示器。这通常是由于在渲染中,某个异步操作(如数据获取、网络请求等)耗时较长,导致组件挂起,从而影响了用户体验。</p>
<p><strong><span style="color: rgba(128, 128, 0, 1)">解决:</span></strong></p>
<p>为了解决这个问题,React 18 引入了一个新的&nbsp;API&nbsp;<code>startTransition</code>,用于告知 React 暂停当前渲染,直到异步操作完成后再继续渲染。你可以在组件中使用<code>startTransition</code>包装异步更新,以避免组件挂起的情况。</p>
<p><strong><span style="color: rgba(128, 128, 0, 1)">具体代码实现:</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">import</span> { useNavigate } from 'react-router-dom'<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 跳转页面</span>
<span style="color: rgba(0, 0, 255, 1)">const</span> navigate =<span style="color: rgba(0, 0, 0, 1)"> useNavigate();
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 跳转到注册页面</span>
<span style="color: rgba(0, 0, 0, 1)">function goRegister(){
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> startTransition,用于告知 React 暂停当前渲染,直到异步操作完成后再继续渲染。</span>
    startTransition(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 包装异步更新,以避免组件挂起的情况。</span>
      navigate("/Register"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 跳转到这个路由下的页面</span>
<span style="color: rgba(0, 0, 0, 1)">    });
}</span></pre>
</div>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/fairya/p/17167049.html
頁: [1]
查看完整版本: 关于React-Router6 (React 路由)