😇
Next.js14, TypeScriptでReduxを使用する際のテーマカラーの切り替え
Reactでreduxを実装するようにやったら沼った件
そういえばNext.js, TypeScriptでRedux実装したことなかったなぁと、素のreactで実装するノリでやってみたらファイルの置き場所間違ってるし、必要なファイル作成してないしで、まあ沼る、沼る(笑)
公式を探したら普通にあったので秒で解決した件
完成リポジトリ
準備
Redux install
npm i @reduxjs/toolkit react-redux
React icon
npm i react-icons
ポイント
公式内にある各ポイントを紹介します。
その1 app/StoreProvider.tsxの作成
app/StoreProvider.tsx
'use client'
import { useRef } from 'react'
import { Provider } from 'react-redux'
import { makeStore, AppStore } from '../lib/store'
export default function StoreProvider({
children
}: {
children: React.ReactNode
}) {
const storeRef = useRef<AppStore>()
if (!storeRef.current) {
// Create the store instance the first time this renders
storeRef.current = makeStore()
}
return <Provider store={storeRef.current}>{children}</Provider>
}
その2 lib/store.tsを作成
import { configureStore } from "@reduxjs/toolkit";
import themeReducer from "../lib/features/theme/themeSlice";
export const makeStore = () => {
return configureStore({
reducer: {
darkTheme: themeReducer,
},
});
};
export type AppStore = ReturnType<typeof makeStore>;
export type RootState = ReturnType<AppStore["getState"]>;
export type AppDispatch = AppStore["dispatch"];
その3 lib/features/theme/themeSlice.ts作成
import { createSlice } from "@reduxjs/toolkit";
type ThemeState = boolean;
const themeLocalStorage = !!localStorage.getItem("movies-theme");
const initialState: ThemeState = themeLocalStorage;
export const themeSlice = createSlice({
name: "theme",
initialState,
reducers: {
toggleTheme: (state) => {
if (state) {
localStorage.removeItem("movies-theme");
} else {
localStorage.setItem("movies-theme", "_");
}
return (state = !state);
},
},
});
export const { toggleTheme } = themeSlice.actions;
export default themeSlice.reducer;
その4 hooks/storeHook.ts作成
import { useDispatch, useSelector, useStore } from "react-redux";
import type { AppDispatch, AppStore, RootState } from "../lib/store";
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes<AppDispatch>();
export const useAppSelector = useSelector.withTypes<RootState>();
export const useAppStore = useStore.withTypes<AppStore>();
その5 tailwind.configに追記
import type { Config } from "tailwindcss";
const config: Config = {
content: [
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
],
darkMode: "class", // ここ追記
theme: {
extend: {
backgroundImage: {
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
"gradient-conic":
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
},
},
},
plugins: [],
};
export default config;
あとはHeaderコンポーネント
によくあるテーマの切り替え設定を実装していくだけとなります。
※Guthubにあります。
まとめ
公式を見ていただくとわかりますが、テーマカラーの切り替え部分以外はほぼそのまんま使用してます。
チャレンジしてダメだったら公式を見よう!ということが再認識できる経験になりました。
Discussion