メインコンテンツにスキップ

Redux Toolkitクイックスタート

学習内容
  • React-ReduxでRedux Toolkitをセットアップして使用する方法
前提条件

はじめに

Redux Toolkitクイックスタートチュートリアルへようこそ! このチュートリアルでは、Redux Toolkitを簡単に紹介し、正しく使い始める方法を説明します

このチュートリアルの読み方

このページでは、Redux Toolkitと使用する主なAPIを使用してReduxアプリケーションをセットアップする方法に焦点を当てます。Reduxとは何か、どのように機能するか、Redux Toolkitの使用方法の完全な例については、「チュートリアルの概要」ページにリンクされているチュートリアルを参照してください

このチュートリアルでは、ReactでRedux Toolkitを使用していると仮定していますが、他のUIレイヤーでも使用できます。例は、すべてのアプリケーションコードがsrcにある典型的なCreate-React-Appフォルダー構造に基づいていますが、パターンは使用しているプロジェクトまたはフォルダーのセットアップに適合させることができます。

Create-React-AppのRedux+JSテンプレートには、この同じプロジェクトセットアップがすでに構成されています。

使用方法の概要

Redux ToolkitとReact-Reduxをインストールする

Redux ToolkitとReact-Reduxパッケージをプロジェクトに追加します

npm install @reduxjs/toolkit react-redux

Reduxストアを作成する

src/app/store.jsという名前のファイルを作成します。Redux ToolkitからconfigureStore APIをインポートします。空のReduxストアを作成し、それをエクスポートすることから始めます

app/store.js
import { configureStore } from '@reduxjs/toolkit'

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

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

これにより、Reduxストアが作成され、開発中にストアを検査できるようにRedux DevTools拡張機能も自動的に構成されます。

ReduxストアをReactに提供する

ストアが作成されたら、src/index.jsでアプリケーションの周りにReact-Redux <Provider>を配置することで、Reactコンポーネントで利用できるようにすることができます。作成したReduxストアをインポートし、<App>の周りに<Provider>を配置し、ストアをpropとして渡します

index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { store } from './app/store'
import { Provider } from 'react-redux'

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

Reduxステータススライスを作成する

src/features/counter/counterSlice.jsという名前の新しいファイルを追加します。そのファイルで、Redux ToolkitからcreateSlice APIをインポートします。

スライスを作成するには、スライスを識別するための文字列名、初期状態値、および状態の更新方法を定義する1つ以上のreducer関数が必要です。スライスが作成されると、生成されたReduxアクションクリエーターとスライス全体のreducer関数をエクスポートできます。

Reduxでは、データのコピーを作成し、コピーを更新することにより、すべての状態更新を不変的に記述する必要があります。ただし、Redux ToolkitのcreateSliceおよびcreateReducer APIは、Immerを内部で使用して、正しい不変更新になる「変更」更新ロジックを記述できるようにします

features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

export interface CounterState {
value: number
}

const initialState: CounterState = {
value: 0,
}

export const counterSlice = createSlice({
name: 'counter',
initialState,
reducers: {
increment: (state) => {
// Redux Toolkit allows us to write "mutating" logic in reducers. It
// doesn't actually mutate the state because it uses the Immer library,
// which detects changes to a "draft state" and produces a brand new
// immutable state based off those changes
state.value += 1
},
decrement: (state) => {
state.value -= 1
},
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload
},
},
})

// Action creators are generated for each case reducer function
export const { increment, decrement, incrementByAmount } = counterSlice.actions

export default counterSlice.reducer

スライスのReducerをストアに追加する

次に、カウンタースライスからreducer関数をインポートし、ストアに追加する必要があります。reducerパラメーター内にフィールドを定義することにより、このスライスreducer関数を使用して、その状態へのすべての更新を処理するようにストアに指示します。

app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'

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

// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch

ReactコンポーネントでReduxの状態とアクションを使用する

React-Reduxフックを使用して、ReactコンポーネントがReduxストアと対話できるようにします。useSelectorでストアからデータを読み取り、useDispatchを使用してアクションをディスパッチできます。<Counter>コンポーネントを含むsrc/features/counter/Counter.jsファイルを作成し、そのコンポーネントをApp.jsにインポートして<App>内にレンダリングします。

features/counter/Counter.js
import React from 'react'
import type { RootState } from '../../app/store'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'

export function Counter() {
const count = useSelector((state: RootState) => state.counter.value)
const dispatch = useDispatch()

return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
)
}

これで、「増やす」ボタンと「減らす」ボタンをクリックするたびに

  • 対応するReduxアクションがストアにディスパッチされます
  • カウンタースライスのreducerはアクションを確認し、その状態を更新します
  • <Counter>コンポーネントは、ストアからの新しい状態値を確認し、新しいデータで自身を再レンダリングします

学習内容

ReactでRedux Toolkitをセットアップして使用する方法の簡単な概要でした。詳細を要約すると

まとめ
  • configureStoreでReduxストアを作成する
    • configureStoreは、名前付き引数としてreducer関数を受け入れます
    • configureStoreは、適切なデフォルト設定でストアを自動的にセットアップします
  • ReduxストアをReactアプリケーションコンポーネントに提供する
    • <App />の周りにReact-Redux <Provider>コンポーネントを配置します
    • Reduxストアを<Provider store={store}>として渡します
  • createSliceでRedux「スライス」reducerを作成する
    • 文字列名、初期状態、および名前付きreducer関数を使用してcreateSliceを呼び出します
    • Reducer関数は、Immerを使用して状態を「変更」する場合があります
    • 生成されたスライスreducerとアクションクリエーターをエクスポートします
  • ReactコンポーネントでReact-Redux useSelector/useDispatchフックを使用する
    • useSelectorフックを使用してストアからデータを読み取る
    • useDispatchフックでdispatch関数を取得し、必要に応じてアクションをディスパッチします

完全なカウンターアプリの例

ここで示されているカウンターの例アプリも

実行中のCodeSandboxとしての完全なカウンターアプリケーションは次のとおりです

次のステップ

Reduxコアドキュメントの「Redux Essentials」および「Redux Fundamentals」チュートリアルを読むことをお勧めします。Reduxのしくみ、Redux Toolkitの機能、および正しく使用する方法を完全に理解できます。