[RFC] 045 - App Layout 重构 #2295
Replies: 1 comment 2 replies
-
设置弹窗拦截路由
目标
背景(目前遗留的社区问题)拦截路由无法受控,不能自由定义什么情况下开启拦截什么情况下关闭拦截,突破限制的方式只有通过 redirect 硬刷新 https://www.reddit.com/r/nextjs/comments/174m3xf/how_to_stop_intercepting_routes_for_some_specific/ "use server";
import { redirect } from "next/navigation";
export default async function redirectHard(uri: string) {
redirect(uri);
} Warning 但测试后发现在 ios 设别上响应很慢,有时候甚至无法响应 设计思路当前的设计思路是通过路由进行受控,例如想实现
会话设置同理
文件结构示意
Fallback 路由示意: 'use client';
import { useLayoutEffect } from 'react';
import urlJoin from 'url-join';
import { useQuery } from '@/hooks/useQuery';
import { useQueryRoute } from '@/hooks/useQueryRoute';
import { SettingsTabs } from '@/store/global/initialState';
/**
* @description: Settings Modal (intercepting routes fallback when hard refresh)
* @example: /settings/modal?tab=common => /settings/common
*/
const SettingsModalFallback = () => {
const { tab = SettingsTabs.Common } = useQuery();
const router = useQueryRoute();
useLayoutEffect(() => {
router.replace(urlJoin('/settings', tab as string), { query: { tab: '' } });
}, []);
return null;
};
export default SettingsModalFallback; 工具 hook由于拦截判断条件比较复杂,包装为两个 hook 方法方便使用 打开设置面板:
export const useOpenSettings = (tab: SettingsTabs = SettingsTabs.Common) => {
const router = useQueryRoute();
const mobile = useIsMobile();
return useMemo(() => {
if (mobile) {
return () => router.push(urlJoin('/settings', tab));
} else {
// use Intercepting Routes on Desktop
return () => router.push('/settings/modal', { query: { tab } });
}
}, [mobile, tab]);
}; 打开角色设置面板:
export const useOpenChatSettings = (
isInbox?: boolean,
tab: ChatSettingsTabs = ChatSettingsTabs.Meta,
) => {
const globalSettings = useOpenSettings(SettingsTabs.Agent);
const router = useQueryRoute();
const mobile = useIsMobile();
return useMemo(() => {
if (isInbox) {
useGlobalStore.setState({
sidebarKey: SidebarTabKey.Setting,
});
return globalSettings;
}
if (mobile) {
return () => router.push('/chat/settings');
} else {
// use Intercepting Routes on Desktop
return () => router.push('/chat/settings/modal', { query: { tab } });
}
}, [globalSettings, mobile, isInbox, tab]);
}; Q&AQ: 为什么不用 Modal 而用现在的方案,优点是什么,缺点是什么?优点:
缺点
Q: 现在这个方案的缺点是否可以在未来基础设施迭代过程中优化掉?(是否等 next 升级或者支持特性,就可以把缺点干掉)增加拦截受控的社区呼声目前也挺高,比如在 Link 或者 router.push 上增加开关控制是否劫持,或者通过 query 判断是否被劫持
如果相关特性能够被支持,整体项目结构会干净很多,不需要用子路由 xxx/modal 包裹也不需要手动处理硬刷新降级逻辑
Q: 对旧路由的影响?没有任何影响,目前的拦截模式是 xxx/modal 老路由不会被拦截 Q: 如果这个方案在后续过程中存在问题,相应的迁移方案是什么?(改成 Modal 要做什么)因为整体收拾的比较干净,所以几乎可以热插拔
|
Beta Was this translation helpful? Give feedback.
-
目标与背景
目标
use client
尽可能原子化Note
平行路由介绍: https://nextjs.org/docs/app/building-your-application/routing/parallel-routes
背景
目前 LobeChat 文件夹目录架构如下:
可以发现如果我想改动助手详情侧边栏,从文件目录上其实很难直观发现我需要去改哪些关联的地方
重构后:
布局示意
例如目前 LobeChat Market 页面的文件夹目录架构如下:
进展
(main)
(main)
layout group #2297@nav
♻️ refactor: Move NavBar to@nav
slot route #2306Beta Was this translation helpful? Give feedback.
All reactions