mirror of
https://github.com/tuono-labs/tuono
synced 2026-07-25 12:52:47 -07:00
feat(packages/tuono-(router|fs-router-vite-plugin)): replace __route with __layout (#283)
This commit is contained in:
committed by
GitHub
parent
cf56b3a53e
commit
0ef1252e1f
@@ -54,7 +54,7 @@ then it will be accessible at `posts/1`, `posts/2`, etc.
|
||||
## The Root route (Layout components)
|
||||
|
||||
Tuono allows you to have a layout component to wrap all the routes included within the same folder.
|
||||
To define such component you will have to create a `__root.tsx` file (is allowed only a single `__root` file per folder).
|
||||
To define such component you will have to create a `__layout.tsx` file (is allowed only a single `__layout` file per folder).
|
||||
|
||||
This file won't generate any route.
|
||||
|
||||
@@ -63,7 +63,7 @@ This file won't generate any route.
|
||||
A file created in this location will wrap all project route.
|
||||
|
||||
```tsx
|
||||
// src/routes/__root.tsx
|
||||
// src/routes/__layout.tsx
|
||||
export default function RootLayout({ children }) {
|
||||
return <main>{children}</main>
|
||||
}
|
||||
@@ -74,8 +74,8 @@ export default function RootLayout({ children }) {
|
||||
A file created in this location will wrap only the routes defined within the `src/routes/posts` folder.
|
||||
|
||||
```tsx
|
||||
// src/routes/posts/__root.tsx
|
||||
export default function PostRootLayout({ children }) {
|
||||
// src/routes/posts/__layout.tsx
|
||||
export default function PostLayout({ children }) {
|
||||
return <article>{children}</article>
|
||||
}
|
||||
```
|
||||
@@ -86,9 +86,9 @@ Referring to the two examples above consider that:
|
||||
|
||||
```tsx
|
||||
<RootLayout>
|
||||
<PostRootLayout>
|
||||
<PostLayout>
|
||||
<ExamplePost />
|
||||
</PostRootLayout>
|
||||
</PostLayout>
|
||||
</RootLayout>
|
||||
```
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use time::OffsetDateTime;
|
||||
use tuono_lib::axum::http::{header, HeaderMap, StatusCode};
|
||||
use tuono_lib::{Request, Response};
|
||||
|
||||
const FILE_TO_EXCLUDE: [&str; 2] = ["sitemap.xml", "__root"];
|
||||
const FILES_TO_EXCLUDE: [&str; 2] = ["sitemap.xml", "__layout"];
|
||||
|
||||
const SITEMAP: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
@@ -20,7 +20,7 @@ fn load_routes() -> Vec<String> {
|
||||
if !entry.is_dir() {
|
||||
let path = clean_path(format!("/{}", entry.to_string_lossy()));
|
||||
|
||||
if !FILE_TO_EXCLUDE
|
||||
if !FILES_TO_EXCLUDE
|
||||
.iter()
|
||||
.any(|exclude| path.ends_with(exclude))
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ use std::process::Stdio;
|
||||
use crate::route::Route;
|
||||
|
||||
const IGNORE_EXTENSIONS: [&str; 3] = ["css", "scss", "sass"];
|
||||
const IGNORE_FILES: [&str; 1] = ["__root"];
|
||||
const IGNORE_FILES: [&str; 1] = ["__layout"];
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const ROUTES_FOLDER_PATH: &str = "\\src\\routes";
|
||||
@@ -333,8 +333,8 @@ mod tests {
|
||||
app.base_path = "/home/user/Documents/tuono".into();
|
||||
|
||||
let routes = [
|
||||
"/home/user/Documents/tuono/src/routes/__root.tsx",
|
||||
"/home/user/Documents/tuono/src/routes/posts/__root.tsx",
|
||||
"/home/user/Documents/tuono/src/routes/__layout.tsx",
|
||||
"/home/user/Documents/tuono/src/routes/posts/__layout.tsx",
|
||||
];
|
||||
|
||||
routes.into_iter().for_each(|route| {
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import type { ReactNode, JSX } from 'react'
|
||||
|
||||
interface RootRouteProps {
|
||||
interface RootLayoutProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export default function RootRoute({ children }: RootRouteProps): JSX.Element {
|
||||
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
import type { ReactNode, JSX } from 'react'
|
||||
|
||||
interface RootRouteProps {
|
||||
interface RootLayoutProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export default function RootRoute({ children }: RootRouteProps): JSX.Element {
|
||||
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { ReactNode, JSX } from 'react'
|
||||
import { MDXProvider } from '@mdx-js/react'
|
||||
|
||||
interface RootRouteProps {
|
||||
interface RootLayoutProps {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export default function RootRoute({ children }: RootRouteProps): JSX.Element {
|
||||
export default function RootLayout({ children }: RootLayoutProps): JSX.Element {
|
||||
return (
|
||||
<html>
|
||||
<body>
|
||||
@@ -10,12 +10,12 @@ const routes = [
|
||||
routePath: '/posts/my-post',
|
||||
variableName: 'PostsMyPost',
|
||||
parent: {
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
path: '/posts/__root',
|
||||
path: '/posts/__layout',
|
||||
cleanedPath: '/posts',
|
||||
children: undefined,
|
||||
},
|
||||
@@ -29,12 +29,12 @@ const routes = [
|
||||
routePath: '/posts/',
|
||||
variableName: 'PostsIndex',
|
||||
parent: {
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/home/valerio/Documents/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/home/valerio/Documents/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
path: '/posts/__root',
|
||||
path: '/posts/__layout',
|
||||
cleanedPath: '/posts',
|
||||
children: undefined,
|
||||
},
|
||||
@@ -48,12 +48,12 @@ const routes = [
|
||||
routePath: '/posts/',
|
||||
variableName: 'PostspostIndex',
|
||||
parent: {
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
path: '/posts/__root',
|
||||
path: '/posts/__layout',
|
||||
cleanedPath: '/posts',
|
||||
children: undefined,
|
||||
},
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
export const ROUTES_FOLDER = './src/routes/'
|
||||
export const ROOT_PATH_ID = '__root'
|
||||
export const LAYOUT_PATH_ID = '__layout'
|
||||
export const GENERATED_ROUTE_TREE = './.tuono/routeTree.gen.ts'
|
||||
|
||||
@@ -18,7 +18,11 @@ import {
|
||||
} from './utils'
|
||||
|
||||
import type { Config, RouteNode } from './types'
|
||||
import { ROUTES_FOLDER, ROOT_PATH_ID, GENERATED_ROUTE_TREE } from './constants'
|
||||
import {
|
||||
ROUTES_FOLDER,
|
||||
LAYOUT_PATH_ID,
|
||||
GENERATED_ROUTE_TREE,
|
||||
} from './constants'
|
||||
|
||||
import { sortRouteNodes } from './sort-route-nodes'
|
||||
import isDefaultExported from './utils/is-default-exported'
|
||||
@@ -154,7 +158,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
|
||||
const routeConfigChildrenText = buildRouteConfig(routeNodes)
|
||||
|
||||
const sortedRouteNodes = multiSortBy(routeNodes, [
|
||||
(d): number => (d.routePath.includes(`/${ROOT_PATH_ID}`) ? -1 : 1),
|
||||
(d): number => (d.routePath.includes(`/${LAYOUT_PATH_ID}`) ? -1 : 1),
|
||||
(d): number => d.routePath.split('/').length,
|
||||
(d): number => (d.routePath.endsWith("index'") ? -1 : 1),
|
||||
(d): RouteNode => d,
|
||||
@@ -179,7 +183,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
|
||||
|
||||
const createRoutes = [
|
||||
...sortedRouteNodes.map((node) => {
|
||||
const isRoot = node.routePath.endsWith(ROOT_PATH_ID)
|
||||
const isRoot = node.routePath.endsWith(LAYOUT_PATH_ID)
|
||||
const rootDeclaration = isRoot ? ', isRoot: true' : ''
|
||||
const variableName = node.variableName as string
|
||||
|
||||
@@ -195,7 +199,7 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
|
||||
return [
|
||||
`const ${variableName}Route = ${variableName}.update({
|
||||
${[
|
||||
!node.path?.endsWith(ROOT_PATH_ID) && `path: '${cleanedPath}'`,
|
||||
!node.path?.endsWith(LAYOUT_PATH_ID) && `path: '${cleanedPath}'`,
|
||||
`getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,
|
||||
rustHandlersNodes.includes(node.path || '')
|
||||
? 'hasHandler: true'
|
||||
@@ -213,15 +217,15 @@ export async function routeGenerator(config = defaultConfig): Promise<void> {
|
||||
'// This file is auto-generated by Tuono',
|
||||
"import { createRoute, dynamic } from 'tuono'",
|
||||
[
|
||||
`import RootImport from './${replaceBackslash(
|
||||
`import RootLayoutImport from './${replaceBackslash(
|
||||
path.relative(
|
||||
path.dirname(config.generatedRouteTree),
|
||||
path.resolve(config.folderName, ROOT_PATH_ID),
|
||||
path.resolve(config.folderName, LAYOUT_PATH_ID),
|
||||
),
|
||||
)}'`,
|
||||
].join('\n'),
|
||||
imports,
|
||||
'const rootRoute = createRoute({ isRoot: true, component: RootImport });',
|
||||
'const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport });',
|
||||
createRoutes,
|
||||
'// Create/Update Routes',
|
||||
createRouteUpdates,
|
||||
|
||||
@@ -13,12 +13,12 @@ const routes = [
|
||||
cleanedPath: '/posts/[post]',
|
||||
},
|
||||
{
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
path: '/posts/__root',
|
||||
path: '/posts/__layout',
|
||||
cleanedPath: '/posts',
|
||||
},
|
||||
{
|
||||
@@ -42,12 +42,12 @@ const routes = [
|
||||
]
|
||||
|
||||
const parent = {
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
path: '/posts/__root',
|
||||
path: '/posts/__layout',
|
||||
cleanedPath: '/posts',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ROOT_PATH_ID } from './constants'
|
||||
import { LAYOUT_PATH_ID } from './constants'
|
||||
import { multiSortBy } from './utils'
|
||||
import type { RouteNode } from './types'
|
||||
|
||||
@@ -19,15 +19,15 @@ export function hasParentRoute(
|
||||
(d): number => d.routePath.length * -1,
|
||||
(d): string | undefined => d.variableName,
|
||||
])
|
||||
// Exclude base __root file
|
||||
.filter((d) => d.routePath !== `/${ROOT_PATH_ID}`)
|
||||
// Exclude base __layout file
|
||||
.filter((d) => d.routePath !== `/${LAYOUT_PATH_ID}`)
|
||||
|
||||
for (const route of sortedNodes) {
|
||||
if (route.routePath === '/') continue
|
||||
|
||||
if (
|
||||
route.routePath.startsWith(parentRoutePath) &&
|
||||
route.routePath.endsWith(ROOT_PATH_ID)
|
||||
route.routePath.endsWith(LAYOUT_PATH_ID)
|
||||
) {
|
||||
return route
|
||||
}
|
||||
|
||||
@@ -22,10 +22,10 @@ const routes = [
|
||||
cleanedPath: '/about',
|
||||
},
|
||||
{
|
||||
filePath: '__root.tsx',
|
||||
filePath: '__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/__root.tsx',
|
||||
routePath: '/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/__layout.tsx',
|
||||
routePath: '/__layout',
|
||||
variableName: 'root',
|
||||
},
|
||||
{
|
||||
@@ -50,10 +50,10 @@ const routes = [
|
||||
variableName: 'PostsIndex',
|
||||
},
|
||||
{
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
},
|
||||
]
|
||||
@@ -78,10 +78,10 @@ const expectedSorting = [
|
||||
cleanedPath: '/about',
|
||||
},
|
||||
{
|
||||
filePath: 'posts/__root.tsx',
|
||||
filePath: 'posts/__layout.tsx',
|
||||
fullPath:
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__root.tsx',
|
||||
routePath: '/posts/__root',
|
||||
'/tuono/packages/tuono-fs-router-vite-plugin/tests/generator/multi-level-root-dynamic/routes/posts/__layout.tsx',
|
||||
routePath: '/posts/__layout',
|
||||
variableName: 'Postsroot',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { RouteNode } from './types'
|
||||
import { multiSortBy } from './utils'
|
||||
import { ROOT_PATH_ID } from './constants'
|
||||
import { LAYOUT_PATH_ID } from './constants'
|
||||
|
||||
// Routes need to be sorted in order to iterate over the handleNode fn
|
||||
// with first the items that might be parent routes
|
||||
@@ -14,4 +14,4 @@ export const sortRouteNodes = (routes: Array<RouteNode>): Array<RouteNode> =>
|
||||
(d): number => (d.filePath.match(/[./]route[.]/) ? -1 : 1),
|
||||
(d): number => (d.routePath.endsWith('/') ? -1 : 1),
|
||||
(d): string => d.routePath,
|
||||
]).filter((d) => ![`/${ROOT_PATH_ID}`].includes(d.routePath || ''))
|
||||
]).filter((d) => ![`/${LAYOUT_PATH_ID}`].includes(d.routePath || ''))
|
||||
|
||||
+2
-2
@@ -2,14 +2,14 @@
|
||||
|
||||
import { createRoute, dynamic } from 'tuono'
|
||||
|
||||
import RootImport from './routes/__root'
|
||||
import RootLayoutImport from './routes/__layout'
|
||||
|
||||
const IndexImport = dynamic(() => import('./routes/index'))
|
||||
const PostscatchallImport = dynamic(
|
||||
() => import('./routes/posts/[...catch_all]'),
|
||||
)
|
||||
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootImport })
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })
|
||||
|
||||
const Index = createRoute({ component: IndexImport })
|
||||
const Postscatchall = createRoute({ component: PostscatchallImport })
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
|
||||
import { createRoute, dynamic } from 'tuono'
|
||||
|
||||
import RootImport from './routes/__root'
|
||||
import RootLayoutImport from './routes/__layout'
|
||||
|
||||
const AboutImport = dynamic(() => import('./routes/about.mdx'))
|
||||
const IndexImport = dynamic(() => import('./routes/index'))
|
||||
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootImport })
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })
|
||||
|
||||
const About = createRoute({ component: AboutImport })
|
||||
const Index = createRoute({ component: IndexImport })
|
||||
|
||||
+9
-9
@@ -2,18 +2,18 @@
|
||||
|
||||
import { createRoute, dynamic } from 'tuono'
|
||||
|
||||
import RootImport from './routes/__root'
|
||||
import RootLayoutImport from './routes/__layout'
|
||||
|
||||
const PostsrootImport = dynamic(() => import('./routes/posts/__root'))
|
||||
const PostslayoutImport = dynamic(() => import('./routes/posts/__layout'))
|
||||
const AboutImport = dynamic(() => import('./routes/about'))
|
||||
const IndexImport = dynamic(() => import('./routes/index'))
|
||||
const PostspostImport = dynamic(() => import('./routes/posts/[post]'))
|
||||
const PostsIndexImport = dynamic(() => import('./routes/posts/index'))
|
||||
const PostsMyPostImport = dynamic(() => import('./routes/posts/my-post'))
|
||||
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootImport })
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })
|
||||
|
||||
const Postsroot = createRoute({ component: PostsrootImport, isRoot: true })
|
||||
const Postslayout = createRoute({ component: PostslayoutImport, isRoot: true })
|
||||
const About = createRoute({ component: AboutImport })
|
||||
const Index = createRoute({ component: IndexImport })
|
||||
const Postspost = createRoute({ component: PostspostImport })
|
||||
@@ -22,7 +22,7 @@ const PostsMyPost = createRoute({ component: PostsMyPostImport })
|
||||
|
||||
// Create/Update Routes
|
||||
|
||||
const PostsrootRoute = Postsroot.update({
|
||||
const PostslayoutRoute = Postslayout.update({
|
||||
getParentRoute: () => rootRoute,
|
||||
})
|
||||
|
||||
@@ -38,17 +38,17 @@ const IndexRoute = Index.update({
|
||||
|
||||
const PostspostRoute = Postspost.update({
|
||||
path: '/posts/[post]',
|
||||
getParentRoute: () => PostsrootRoute,
|
||||
getParentRoute: () => PostslayoutRoute,
|
||||
})
|
||||
|
||||
const PostsIndexRoute = PostsIndex.update({
|
||||
path: '/posts',
|
||||
getParentRoute: () => PostsrootRoute,
|
||||
getParentRoute: () => PostslayoutRoute,
|
||||
})
|
||||
|
||||
const PostsMyPostRoute = PostsMyPost.update({
|
||||
path: '/posts/my-post',
|
||||
getParentRoute: () => PostsrootRoute,
|
||||
getParentRoute: () => PostslayoutRoute,
|
||||
})
|
||||
|
||||
// Create and export the route tree
|
||||
@@ -56,7 +56,7 @@ const PostsMyPostRoute = PostsMyPost.update({
|
||||
export const routeTree = rootRoute.addChildren([
|
||||
IndexRoute,
|
||||
AboutRoute,
|
||||
PostsrootRoute.addChildren([
|
||||
PostslayoutRoute.addChildren([
|
||||
PostsMyPostRoute,
|
||||
PostsIndexRoute,
|
||||
PostspostRoute,
|
||||
|
||||
+2
-2
@@ -2,13 +2,13 @@
|
||||
|
||||
import { createRoute, dynamic } from 'tuono'
|
||||
|
||||
import RootImport from './routes/__root'
|
||||
import RootLayoutImport from './routes/__layout'
|
||||
|
||||
const AboutImport = dynamic(() => import('./routes/about'))
|
||||
const IndexImport = dynamic(() => import('./routes/index'))
|
||||
const PostsMyPostImport = dynamic(() => import('./routes/posts/my-post'))
|
||||
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootImport })
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })
|
||||
|
||||
const About = createRoute({ component: AboutImport })
|
||||
const Index = createRoute({ component: IndexImport })
|
||||
|
||||
+2
-2
@@ -2,12 +2,12 @@
|
||||
|
||||
import { createRoute, dynamic } from 'tuono'
|
||||
|
||||
import RootImport from './routes/__root'
|
||||
import RootLayoutImport from './routes/__layout'
|
||||
|
||||
const AboutImport = dynamic(() => import('./routes/about'))
|
||||
const IndexImport = dynamic(() => import('./routes/index'))
|
||||
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootImport })
|
||||
const rootRoute = createRoute({ isRoot: true, component: RootLayoutImport })
|
||||
|
||||
const About = createRoute({ component: AboutImport })
|
||||
const Index = createRoute({ component: IndexImport })
|
||||
|
||||
@@ -42,7 +42,7 @@ interface TraverseRootComponentsProps<TData = unknown> {
|
||||
|
||||
/*
|
||||
* This component traverses and renders
|
||||
* all the components that wraps the selected route (__root).
|
||||
* all the components that wraps the selected route (__layout).
|
||||
* The parents components need to be memoized in order to avoid
|
||||
* re-rendering bugs when changing route.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user