前言
next.js新增了一个平行路由的概念,问题是react这么多年了也没平行路由,react router里也没有,为next.js要新增一个?和之前相比,平行路由有什么区别?
先说如何创建
并行路由是通过命名插槽创建的。插槽使用@符号开头,比如 @folder
。例如,以下文件结构定义了两个插槽: @analytics
和 @team
: 这个写法和react之前的props传递组件可以说一模一样,先来回顾一下纯react传递组件是用来干嘛的
ts
// Test
const Test = (props: any) => {
return (
<div>
{props?.header}
{props.children}
</div>
);
};
export default Test;
//使用Test,场景1
<Test header={<Header />}>
// children部分
<div>
<h1>Hello</h1>
</div>
</Test>
// 场景2
<Test>
<div>
<h1>Hello</h1>
</div>
</Test>
简单的说就是有多处需要使用某个组件,但是每处又有差别,需要自定义。
问题来了,既然react之前也能实现类似插槽的功能,为啥还要在next.js中多出一个平行路由的概念,肯定有不一样的部分,主要有如下用法
条件渲染
当需要在同一个路径为不同的用户展示不同的页面时,例如,为 /admin
或 /user
角色渲染不同的仪表板页面:
next.js官方示意图 很常用,但是在react中要实现类似的功能也是一样的代码,可以说如果只是为了根据条件来展示不同的页面,用不用平行路由无所谓,如果只是判断条件就用上平行路由,动力有点不足,接着往下看。
标签组
官网的名字叫Tab Groups,但是我看了下功能基本就类似react router的嵌套路由,倒是挺简单,在平行路由下单独声明一个layout文件,同时创建一个page-views和visitors,了解next.js的小伙伴大概就能猜到了,这里的两个新页面肯定会套在新建的layout下。 没有什么特殊的意义,主要作用就是创建一个新的
group
,方便更好的管理代码结构。
允许为每个路由定义独立的错误和加载状态
想象一个仪表盘需求,包含用户统计,流量分析等多个模块,在之前的react中,通常是这么写
ts
function Dashboard() {
return (
<div>
<Analytics />
<UserList />
<Notifications />
</div>
);
}
是的,就是简单的组件组合,甚至连props传组件都用不上,因为我不需要某个模块从外部传入。跟之前的react router也没类似的实现,现在其中一个模块报错,整个页面都会崩溃,也不是没有解决的办法,使用ErrorBoundary
ts
import Test from "./Test";
import Test2 from "./Test2";
import { ErrorBoundary } from "react-error-boundary";
export default function Settings() {
return (
<div>
<ErrorBoundary fallback={<div>Error</div>}>
<h1>Settings</h1>
<Test />
<Test2 />
</ErrorBoundary>
</div>
);
}
// Test抛出错误
export default function Test() {
throw new Error("Test error");
return <div>Test</div>;
}
但是稍微麻烦点,要安装一个新库,而且现在Test和Test2共用一个Error,如果不想共用就得写两个,就像这样: 总之就是不好维护,在next中就方便了很多(也并没有),只需要声明error.tsx文件或者loading.tsx文件,说白了就是内置了一些功能
@dashboard/page.tsx抛出的错误,会被同级的error.tsx捕获,不会影响其他页面正常使用。而且各个模块并行渲染,理论上会更快,但是我也没遇到哪个页面大到能把别的页面卡死,要真出现这种还是赶紧想办法优化吧
另外,我写了这么多年前端,也没遇到前端报错需要不影响其他页面继续使用的场景,都报错了前后端在测试环境就赶紧修bug吧,还想上生产?也可能是跟我待的是小厂的原因?总之这个ErrorBoundary
我知道它可以让页面更完善但是基本没用过。
default.ts
nextjs里很重要的一个概念,简单的理解,就是保底,当路径不匹配的时候,就显示default的内容, 但是唯一让我纠结的是我要不要在平行路由里抛弃page.tsx,一般刷新后我是希望显示的页面和没刷新前一样的,压根不需要什么保底内容,那么这样我是不是可以直接写default.tsx,如果有哪里说的不对希望大佬帮我纠正下。
结尾,总结下平行路由的几个关键点
- 条件判断,其实跟react之前的写法一致,就是更方便的管理文件结构了
- 独立的状态管理,这个还可以,各个平行路由独立工作,不相互影响,可以一些大用户量的C端项目比较需要。
- 标签组,其实就是给平行路由新开一个layout,强化一下布局。 综上所述,平行路由还是有些好处的,但是有个很尴尬的问题,我到现在也没明白为啥刷新后默认去找default.tsx,而不是直接找page.tsx