react-router-dom@6尝鲜

之前在开发React应用的时候,使用react-router总有些奇怪的感觉,觉得React的路由做得没有vue.js完美。最近想到react-router-dom已经有6版本了,于是决定体验一把。

首先创建一个干净的React应用

yarn create react-app react-router-dom-6-demo

查看react-router-dom所有版本

npm view react-router-dom versions

详细的版本列表如下,其中省略了部分目前来说不重要的版本,而6.0版本目前已经进行到beta测试

[
  ...
  '4.0.0',
  ...
  '5.0.0',
  '5.0.1',
  '5.1.0',
  '5.1.1',
  '5.1.2',
  '5.2.0',
  '6.0.0-alpha.0',
  '6.0.0-alpha.1',
  '6.0.0-alpha.2',
  '6.0.0-alpha.3',
  '6.0.0-alpha.4',
  '6.0.0-alpha.5',
  '6.0.0-beta.0'
]

那么废话不多说,直接下载最后一个版本6.0.0-beta.0

cd react-router-dom-6-demo
yarn add react-router-dom@next

然后打开项目文件,稍作整理,只留下最简洁的内容,保留的文件如下:


image.png

然后,尝试从react-router-dom中import部分组件的时候,直接爆了个错误


image.png

不要慌,直接手动安装history依赖库,即可立即解决问题。

yarn add history

另外,经过一顿尝试,在将react-router-dom版本切换到6.0.0-alpha.5的时候,一切都安静了。

yarn remove react-router-dom react-router
yarn add react-router@6.0.0-alpha.5 react-router-dom@6.0.0-alpha.5

好吧,环境已经准备好,这还只是开始,接下来就开始动手做一些路由相关的测试。

首先准备以下页面:


image.png

首先是主页面mian和欢迎页welcome,如果已经登录则进入主页面,否则进去欢迎页(这里以sessionStorage中是否存在token区分是否已登录),欢迎页中点击登录会记录token并跳转至主页面。

接着对App.js进行改造

import React from "react";
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
import Main from "./pages/main";
import Welcome from "./pages/welcome";
import NotFound from "./pages/not-found";
import Page1 from "./pages/page1";
import Page11 from "./pages/page1-1";
import Page12 from "./pages/page1-2";
import Page13 from "./pages/page1-3";
import Page2 from "./pages/page2";
import Page3 from "./pages/page3";

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Test />} >
          <Route path="/home" element={<Main />} ></Route>
          <Route path="/page1" element={<Page1 />}>
            <Route path="/page1-1" element={<Page11 />}></Route>
            <Route path="/page1-2" element={<Page12 />}></Route>
            <Route path="/page1-3" element={<Page13 />}></Route>
          </Route>
          <Route path="/page2" element={<Page2 />}></Route>
          <Route path="/page3" element={<Page3 />}></Route>
        </Route>
        <Route path="/login" element={<Welcome />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
};

export default App;

function Test() {
  return sessionStorage.getItem("token") ? <Main /> : <Navigate to="/login" />;
}

另外主页面和欢迎页代码如下:

main.jsx

import React from "react";
import { useNavigate, Outlet } from "react-router-dom";

const Main = (props) => {

    const navigate = useNavigate();

    const nav = (path) => {
        navigate(path);
    }
    
    return (
        <React.Fragment>
            <div>
                <p>main page</p>
                <button onClick={() => nav("/")}>Home</button>
                <button onClick={() => nav("/page1")}>page1</button>
                <button onClick={() => nav("/page2")}>page2</button>
                <button onClick={() => nav("/page3")}>page3</button>
                <button onClick={() => nav("/page1/page1-2")}>page1-2</button>
                <button onClick={() => nav("/page1/page1-3")}>page1-3</button>
                <Outlet />
            </div>
        </React.Fragment>
    );
};

export default Main;

welcome.jsx

import React from "react";
import { useNavigate } from "react-router-dom";

const Welcome = (props) => {

    const navigate = useNavigate();

    const login = () => {
        sessionStorage.setItem("token", "xx");
        navigate("/", { replace: true });
    };

    return (
        <React.Fragment>
            <button ghost onClick={login}>login</button>
        </React.Fragment>
    );
};

export default Welcome;

mian页面中包含三个子组件page1、page2、page3,而page1中又包含了三个子页面。

page1.jsx

import React from "react";
import { Outlet } from "react-router-dom";

const Main = (props) => {
    return (
        <React.Fragment>
            <p>page 1</p>
            <Outlet />
        </React.Fragment>
    );
};

export default Main;

最终页面层次结构如下


image.png

最后做个总结,react-router-dom@6相比之前的版本存在以下一些变化(以上demo中涉及到的)
1.BrowserRouter保持不变;
2.Switch替换成了Routes;
3.Route中统一使用element属性,去掉原来的component和render;
4.子路由可以省略上级路由了,比如/page1/page1-1以往需要写完整的Path,而目前可以继承上级页面的路由了,甚至斜线都可以省略;
5.useNavigate取代useHistory,并且api也有相应的变化;
6.新增了Outlet,作用相当于{this.props.children}

总而言之,从主观上看,react-router-dom@6新版本的命名更加容易理解,使用更为简洁了,期待正式版本赶紧发布。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,839评论 6 482
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,543评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,116评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,371评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,384评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,111评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,416评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,053评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,558评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,007评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,117评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,756评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,324评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,315评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,539评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,578评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,877评论 2 345

推荐阅读更多精彩内容