-
-
Notifications
You must be signed in to change notification settings - Fork 70
refactor(routing): use router index file #463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { redirect } from "@/hooks/useHashRoute"; | ||
import { goTo } from "@/router"; | ||
import { gameListFetcher } from "@/pages/dashboard/DashBoard"; | ||
import useEditorStore from "@/store/useEditorStore"; | ||
import { GameEditorContext, createGameEditorStore } from "@/store/useGameEditorStore"; | ||
|
@@ -11,15 +11,15 @@ const GameEditorProvider = ({ children }: { children: ReactNode }) => { | |
const gameDir = useEditorStore.use.subPage(); | ||
|
||
if (page !== 'game' || !gameDir) { | ||
redirect('dashboard', 'game'); | ||
goTo('dashboard', 'game'); | ||
}; | ||
|
||
const { data: gameList, isLoading: gameListLoading } = useSWR("game-list", gameListFetcher); | ||
const fristLoading = gameListLoading && !gameList; | ||
const inGameList = gameList && gameList.length > 0 && gameList.some((game) => game.dir === gameDir); | ||
|
||
if (!fristLoading && !inGameList) { | ||
redirect('dashboard', 'game'); | ||
goTo('dashboard', 'game'); | ||
} | ||
Comment on lines
21
to
23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
return ( | ||
|
@@ -45,4 +45,4 @@ const GameEditorContextProvider = ({ children }: { children: ReactNode }) => { | |
); | ||
}; | ||
|
||
export default GameEditorProvider; | ||
export default GameEditorProvider; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import { redirect } from "@/hooks/useHashRoute"; | ||
import { goTo } from "@/router"; | ||
import { templateListFetcher } from "@/pages/dashboard/DashBoard"; | ||
import useEditorStore from "@/store/useEditorStore"; | ||
import { TemplateEditorContext, createTemplateEditorStore } from "@/store/useTemplateEditorStore"; | ||
|
@@ -11,15 +11,15 @@ const TemplateEditorProvider = ({ children }: { children: ReactNode }) => { | |
const templateDir = useEditorStore.use.subPage(); | ||
|
||
if (page !== 'template' || !templateDir) { | ||
redirect('dashboard', 'template'); | ||
goTo('dashboard', 'template'); | ||
} | ||
Comment on lines
13
to
15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When a component redirects, it's a good practice to stop its rendering process to avoid unnecessary computations. Here, the component continues to render after if (page !== 'template' || !templateDir) {
goTo('dashboard', 'template');
return null;
} |
||
|
||
const {data: templateList, isLoading: templateListLoading} = useSWR("template-list", templateListFetcher); | ||
const fristLoading = templateListLoading && !templateList; | ||
const inTemplateList = templateList && templateList.length > 0 && templateList.some((template) => template.dir === templateDir); | ||
|
||
if (!fristLoading && !inTemplateList) { | ||
redirect('dashboard', 'template'); | ||
goTo('dashboard', 'template'); | ||
} | ||
Comment on lines
21
to
23
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
return ( | ||
|
@@ -38,7 +38,7 @@ const TemplateEditorProvider = ({ children }: { children: ReactNode }) => { | |
const TemplateEditorContextProvider = ({ children }: { children: ReactNode}) => { | ||
const page = useEditorStore.use.page(); | ||
const subPage = useEditorStore.use.subPage(); | ||
if (page !== 'template' || !subPage) redirect('dashboard'); | ||
if (page !== 'template' || !subPage) goTo('dashboard'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
const templateEditorStore = useRef(createTemplateEditorStore(subPage)).current; | ||
return( | ||
<TemplateEditorContext.Provider value={templateEditorStore}> | ||
|
@@ -47,4 +47,4 @@ const TemplateEditorContextProvider = ({ children }: { children: ReactNode}) => | |
); | ||
}; | ||
|
||
export default TemplateEditorProvider; | ||
export default TemplateEditorProvider; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import { useEffect, type ReactNode } from 'react'; | ||
import useEditorStore from '@/store/useEditorStore'; | ||
import DashBoard from '@/pages/dashboard/DashBoard'; | ||
import GameEditorProvider from '@/pages/editor/GameEditorProvider'; | ||
import Editor from '@/pages/editor/Editor'; | ||
import TemplateEditorProvider from '@/pages/templateEditor/TemplateEditorProvider'; | ||
import TemplateEditor from '@/pages/templateEditor/TemplateEditor'; | ||
|
||
export type IPage = 'dashboard' | 'game' | 'template'; | ||
|
||
export const routes: { [key in IPage]: { url: string; element: ReactNode } } = { | ||
dashboard: { | ||
url: '#/dashboard', | ||
element: <DashBoard />, | ||
}, | ||
game: { | ||
url: '#/game', | ||
element: ( | ||
<GameEditorProvider> | ||
<Editor /> | ||
</GameEditorProvider> | ||
), | ||
}, | ||
template: { | ||
url: '#/template', | ||
element: ( | ||
<TemplateEditorProvider> | ||
<TemplateEditor /> | ||
</TemplateEditorProvider> | ||
), | ||
}, | ||
}; | ||
|
||
export function RouterPage({ page }: { page: IPage }) { | ||
return routes[page].element || routes.dashboard.element; | ||
} | ||
|
||
export const goTo = (page: IPage, subPage?: string) => { | ||
window.location.hash = `${routes[page].url}${subPage ? `/${subPage}` : ''}`; | ||
}; | ||
|
||
export function useHashRouter() { | ||
const updatePage = useEditorStore.use.updatePage(); | ||
const updateSubPage = useEditorStore.use.updateSubPage(); | ||
|
||
useEffect(() => { | ||
const handleHashChange = () => { | ||
const [, _page, _subPage] = window.location.hash.split('/'); | ||
if (['game', 'template'].includes(_page) && _subPage && _subPage.length > 0) { | ||
updatePage(_page as IPage); | ||
try { | ||
updateSubPage(decodeURIComponent(_subPage)); | ||
} catch (error) { | ||
console.warn('Update sub page error!', error); | ||
updateSubPage(_page); | ||
goTo('dashboard', _page); | ||
} | ||
} else if (_page === 'dashboard' && ['game', 'template'].includes(_subPage)) { | ||
updatePage('dashboard'); | ||
updateSubPage(_subPage); | ||
} else { | ||
updateSubPage('game'); | ||
goTo('dashboard', 'game'); | ||
} | ||
}; | ||
handleHashChange(); | ||
window.addEventListener('hashchange', handleHashChange); | ||
return () => { | ||
window.removeEventListener('hashchange', handleHashChange); | ||
}; | ||
}, []); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a component redirects, it's a good practice to stop its rendering process to avoid unnecessary computations and potential side effects from hooks that run after the redirection logic. Here, the component continues to render after
goTo
is called. You should addreturn null;
to exit early. This also allows removing the redundant semicolon on line 15.