.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

Redux対応を行う。

詳細

修正内容1

Reduxのインストール

npm install @reduxjs/toolkit react-redux

State・Reducerを定義

Provider で App 囲む

src/main.tsx(修正)

Provider で App 全体を囲みます。
tsximport { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { Provider } from 'react-redux'        // ← 追加
import { store } from './store'               // ← 追加
import App from './App'
import './index.css'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <Provider store={store}>                  {/* ← 追加 */}
      <App />
    </Provider>
  </StrictMode>,
)

Counterを修正

src/pages/Counter.tsx(修正)

import * as React from 'react';

// Redux 関連のインポート
import { useSelector, useDispatch } from 'react-redux';
import type { RootState, AppDispatch } from '../store';
import { increment, reset } from '../store/counterSlice';

// --- 既存コード

// Propsの型定義
type CounterProps //= {};
= {
  currentCount: number;
  onIncrement: () => void;
  onReset: () => void;
};

// Stateの型定義
type CounterState = {
  currentCount: number;
};

// 以下、Redux修正あり
// クラス名称を変更
export class Counter_org extends React.Component<CounterProps, CounterState> {
  constructor(props: CounterProps) {
    super(props);
    this.state = { currentCount: 0 };
  }

  // Reduxのdispatchを呼び出す形に変更
  render() {
    return (
      <div>
        <h1>Counter</h1>
        <p>This is a simple example of a React component.</p>
        <p>Current count: <strong>{this.props.currentCount}</strong></p>
        <button className='btn-primary' onClick={() => this.props.onIncrement()}>
          Increment
        </button>
        <button className='btn-primary' onClick={() => this.props.onReset()}>
          Reset
        </button>
      </div>
    );
  }

  /*incrementCounter() {
    this.setState({
      currentCount: this.state.currentCount + 1,
    });
  }*/
}

// --- Reduxラッパー ---
export const Counter = () => {
  const currentCount = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch<AppDispatch>();

  // dispatch の戻り値を void に吸収させる
  const handleIncrement = (): void => { dispatch(increment()); };
  const handleReset = (): void => { dispatch(reset()); };

  return (
    <Counter_org
      currentCount={currentCount}
      onIncrement={handleIncrement}
      onReset={handleReset}
    />
  );
};

修正内容2

Redux対応の効果を観測するためにsrc\pages\Counter.tsxのcount情報をsrc\pages\About.tsxでも使用したい。どの様に変更しますか?以下は前提となる現実装の情報です。

* src\main.tsx

```typescriptreact
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App.tsx'

// Redux 関連のインポート
import { Provider } from 'react-redux'
import { store } from './store'

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </StrictMode>,
)

```

* src\store\index.ts

```typescript
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from './counterSlice'

export const store = configureStore({
  reducer: {
    counter: counterReducer,
  },
})

// 型エクスポート(useSelector / useDispatch で使用)
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
```

* src\store\counterSlice.ts

```typescript
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

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: PayloadAction<number>) => {
      state.value += action.payload
    },
    reset: (state) => {
      state.value = 0
    },
  },
})

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

```

CounterのRedux対応

修正内容1」で変更済み。

AboutにuseSelectorを追加

src/pages/About.tsx(修正)

tsx// 追加するインポート
import { useSelector } from 'react-redux'
import type { RootState } from '../store'

export default function About() {
  // Reduxのstoreからcount値を取得
  const count = useSelector((state: RootState) => state.counter.value)

  return (
    <div>
      <h1>About</h1>
      {/* count情報を表示 */}
      <p>現在のカウント: {count}</p>
    </div>
  )
}

参考


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS