Your cart is currently empty!
Remix Nested Route(嵌套路由) Explained
對剛開始學 Remix 的人,他的路由系統應該會看得很辛苦,沒關係我也是,所以就寫了這篇來記錄一下該怎麼好好的寫好這些路由。
Reference: https://remix.run/docs/en/main/components/outlet、https://remix.run/docs/en/main/file-conventions/routes
解釋影片:https://www.youtube.com/watch?v=QONJCXsZt58
Route Demo:https://interactive-remix-routing-v2.netlify.app
Remix Route 名詞解釋
1. Route
在你的 route 裡面,長 your_route.tsx 會自動產生一個 route,可以從 /your_route 進入。在 Filing 系統中,你的檔案夾名稱就會是 route,而 Remix 會自動取得檔案夾下面的 route.tsx 檔案,例如你儲存 app/your_route/route.tsx,就等於你直接使用 app/your_route.tsx。
2. Parent
每個 Route 只要在檔案裡面加入 <Outlet />,就會變成 Parent,然後在 Outlet 的地方渲染 Child,可以傳遞 context={data} 給 Child。
3. Child
在 Child 內使用 useOutletContext() 取得 Parent 傳來的 context data。例如 your_route.tsx 是你的 parent,child 是 your_route.child.tsx,你可以前往 /your_route/child。
4. Index
每個 route parent 檔案裡如果包含 <Outlet />,你就可以使用 your_route._index.tsx 來作為 /your_route 的 Outlet,所以前往 /your_route 會在 Outlet 渲染 index 的檔案。
5. Dynamic route
可以使用 your_route.$your_id.tsx 來產生動態 route,前往 /your_route/abc,你就可以在檔案內呼叫 params 取得 abc。
Flat routing & Folder routing in Remix
在 V2,Remix 已經不支援 Folder Nesting 了,而是保持 Flat Route,我想應該是因為 name routing 就可以排序,不需要多此一局使用 Folder。可以看看下面兩個連結,也可以看出 Remix 真是會聽使用者意見欸!
>> Upgrading to the new convention: https://remix.run/docs/en/main/start/v2#upgrading-to-the-new-convention
>> Origin Flat Route Proposal: https://github.com/remix-run/remix/discussions/4482
上圖可以看到 Invoice id 從 Invoices 的 <Outlet /> 長出來;Invoices 從 Sales 的 <Outlet /> 長出來;Sales 從 Root 的 <Outlet /> 長出來。
最基本的 Remix Route
// app/route/parent.tsx
export default function SomeParent() {
return (
<>
<div>
<h1>Parent Content</h1>
</div>
</>
);
}
加入 Outlet 讓他變成 Parent
加入 Outlet
// app/route/parent.tsx
import { Outlet } from "@remix-run/react";
export default function SomeParent() {
const myContextValue = { foo: "bar" };
return (
<>
<div className="parent-content">
<h1>Parent Content</h1>
<Outlet context={myContextValue} />
<p>{JSON.stringify(myContextValue)}</p>
</div>
</>
);
}
加入 parent._index.tsx
export default function Child_index() {
return (
<div>
<h1>Index</h1>
</div>
);
}
有漸漸理解了嗎?Index 從 parent.tsx 的 Outlet 長出來了!
加入 Child
// parent.child.tsx
import { useOutletContext } from "@remix-run/react"
export default function Child() {
const myContextValue = useOutletContext();
return (
<>
<p>this is child + {JSON.stringify(myContextValue)}</p>
</>
);
}
可以看到 Parent Content 和最後的<p> {“foo”:”bar”} 是來自 Parent,而<p> this is child + {} 是來自 child。如此就跟官網所說的一樣了!