Boggleを作っています⑧
前回の続き -Boggle game
タイマーを作りました。
State managementにはContextを使っています。
Next.jsにまだ慣れていませんが、基本私は小さいコンポーネントをたくさん作るよう教わったのでその癖もあって、アプリが小さいファイルだらけになっています。
なぜ細かくするかというと単純に、読みやすいからと、変更することがあったら簡単、と言うことです。
毎回毎回component同士にpropsを渡しまくっていて面倒になったので、1発、上の階層からcontextを使いました。
Context Providerを作る
app/context/TimerContext.tsxみたいな場所に作りました。
...
const TimerContext = createContext<TimerContext | null>(null);
export type TimerContext = { // 別ファイルで使える
timed: boolean;
setTimed: React.Dispatch<React.SetStateAction<boolean>>;
timer: number;
setTimer: React.Dispatch<React.SetStateAction<number>>;
};
export default function TimerContextProvider({
children,
}: {
children: React.ReactNode;
}) {
const [timed, setTimed] = useState<boolean>(false);
const [timer, setTimer] = useState<number>(0);
return (
<TimerContext.Provider value={{ timed, setTimed, timer, setTimer }}>
{children}
</TimerContext.Provider>
);
}
export function useTimerContext() { // 別ファイルで使える
const context = useContext(TimerContext);
if (context === undefined) {
throw new Error(
"useTimerContext must be used within a TimerContextProvider"
);
}
return context;
}
上から置いておく
私の場合はapp/layout.tsxみたいな場所に置きました。
...
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={inter.className}
>
<AppRouterCacheProvider>
<NavLayout>
<TimerContextProvider> // ここ
<Container>{children}</Container>
</TimerContextProvider>
</NavLayout>
</AppRouterCacheProvider>
</body>
</html>
);
}
使うとき
普通にインポートしてあとはuseState hookみたいにして簡単です。
import { useTimerContext, TimerContext } from "../context/TimerContext";
...
const { setTimed, timer, setTimer } = useTimerContext() as TimerContext; // useStateみたい
タイマーのリセットにuseEffectとuseRefを使いました。これはまた後日書こうかな。。。
Boggleよりもプロジェクトの方が忙しいので前のように毎日できていませんが、息抜きの勉強になってて楽しいです。
この記事が気に入ったらサポートをしてみませんか?