0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

(Redux)Redux Toolkit、React-Redux の導入

Last updated at Posted at 2024-09-30

(Redux)Redux Toolkit、React-Reduxの導入から動作チェックまで

version
Next.js:14.2.9
Typescript: 8.5.0
React:18.3.1
reduxjs/toolkit:2.2.7
react-redux:9.1.2
Tailwindcss:3.4.1

目的

アプリケーションの開発において、状態管理を効率的かつ一元的に行うため

参考記事


1.インストール

Redux Toolkit は、最新の Redux のベストプラクティスが詰め込まれており、複雑な設定なしで利用できるため、推奨とされる。

npm install @reduxjs/toolkit react-redux

2.Reduxのstoreを作成

/app ディレクトリを使う構成で、store.tsを作成。

/app/store/store.ts

import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
// 例: slice のインポート
import counterReducer from './features/counterSlice';

// ストアを作成
export const store = configureStore({
  reducer: {
    // ここに他のスライスを追加
    counter: counterReducer,
  },
});

// 型定義
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;

// カスタムフック
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;


3. ReduxのSliceの作成

Sliceは、状態とアクションを定義したモジュール。

/app/store/features/counterSlice.ts

import { createSlice } from '@reduxjs/toolkit';

export interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0,
};

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action) => {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;



4.Providerの設定

Providerをアプリ全体に提供するため_app.tsxファイルを設定。
Next.js 14 のappディレクトリを使用する場合、layout.tsxProvider を設定。

/app/layout.tsx

import './globals.css';
import { Inter } from 'next/font/google';
import { Providers } from './providers';

const inter = Inter({ subsets: ['latin'] });

export const metadata = {
  title: 'Next.js Redux App',
  description: 'A sample Next.js app with Redux',
};

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <Providers>{children}</Providers>
      </body>
    </html>
  );
}


/app/providers.tsx

'use client';

import { Provider } from 'react-redux';
import { store } from './store/store';

export function Providers({ children }: { children: React.ReactNode }) {
  return <Provider store={store}>{children}</Provider>;
}


5. コンポーネントで Redux を使用

Redux の状態とアクションをコンポーネント内で使用する為に、useAppSelectoruseAppDispatch を使う。
/app/page.tsx

'use client';

import { useAppDispatch, useAppSelector } from './store/store';
import { increment, decrement } from './store/features/counterSlice';

export default function Home() {
  const count = useAppSelector((state) => state.counter.value);
  const dispatch = useAppDispatch();

  return (
    <div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
      <h1 className="text-4xl font-bold mb-4">Count: {count}</h1>
      <div className="space-x-4">
        <button
          onClick={() => dispatch(increment())}
          className="px-4 py-2 bg-blue-500 text-white font-semibold rounded-lg shadow-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75 transition"
        >
          Increment
        </button>
        <button
          onClick={() => dispatch(decrement())}
          className="px-4 py-2 bg-red-500 text-white font-semibold rounded-lg shadow-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-400 focus:ring-opacity-75 transition"
        >
          Decrement
        </button>
      </div>
    </div>
  );
}




動作チェック

1.ローカル環境で立ち上げる

ターミナルで下記コマンドを実行しhttp://localhost:3000にアクセス
指定のポート番号がある場合は、その番号にアクセスする

npm run dev

2.ボタンをクリック

Increment(+1)もしくはDecrement(-1)をクリックし動作をチェック

image.png



まとめ

Redux ToolkitReact-Redux をインストール。
storeの作成: store.tsconfigureStore を使ってストアを定義。
Sliceの作成: createSlice を使って状態とアクションを定義。
Provider の設定: layout.tsxProvider をラップ。
・コンポーネントで Redux を使用: useAppSelectoruseAppDispatch を使って状態とアクションをコンポーネント内で利用。

これで、Next.js 14 で Redux を導入して状態管理を行うことができる。

補足

Tailwindcssのスタイリング

px-4 py-2: ボタンの左右に 16px41rem = 16px に基づく)と上下に 8px のpaddingを追加。
bg-blue-500bg-red-500: Increment ボタンには青、Decrement ボタンには赤の背景色を指定。
text-white: ボタン内のテキストを白色に指定。
font-semibold: テキストを少し太く(font-weight: 600)することで、読みやすさを向上。
rounded-lg: ボタンの角を丸く(large サイズ)する。
shadow-md: 中程度のシャドウ効果を適用し、ボタンに立体感を追加。
hover:bg-blue-700hover:bg-red-700: マウスオーバー時に、ボタンの背景色をより濃く変更することでインタラクションを強調。
focus:outline-none: フォーカス時にブラウザのデフォルトのアウトラインを消す。
focus:ring-2 focus:ring-blue-400 focus:ring-opacity-75: フォーカス時に外側に青色のリングを表示(ring 効果)、透明度は 75% に設定。
transition: ホバーやフォーカスの状態変化時に滑らかなアニメーション効果を適用。

全体のレイアウト

flex flex-col items-center justify-center min-h-screen: 縦方向に中央揃え、画面の高さいっぱいを使う。
space-x-4: ボタン間の水平方向の余白を 1rem(16px)追加。

上記スタイリングでIncrement ボタンは青、Decrement ボタンは赤になり、ホバーやフォーカス時に色が変わる。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?