Redux Toolkitクイックスタート
- React-ReduxでRedux Toolkitをセットアップして使用する方法
- ES6の構文と機能に精通していること
- React用語の知識:JSX、状態、関数コンポーネント、Props、およびHooks
- Reduxの用語と概念を理解していること
はじめに
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ストアを作成し、それをエクスポートすることから始めます
- TypeScript
- JavaScript
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
import { configureStore } from '@reduxjs/toolkit'
export const store = configureStore({
reducer: {},
})
これにより、Reduxストアが作成され、開発中にストアを検査できるようにRedux DevTools拡張機能も自動的に構成されます。
ReduxストアをReactに提供する
ストアが作成されたら、src/index.js
でアプリケーションの周りにReact-Redux <Provider>
を配置することで、Reactコンポーネントで利用できるようにすることができます。作成したReduxストアをインポートし、<App>
の周りに<Provider>
を配置し、ストアをpropとして渡します
- TypeScript
- JavaScript
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')
)
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を内部で使用して、正しい不変更新になる「変更」更新ロジックを記述できるようにします。
- TypeScript
- JavaScript
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
import { createSlice } from '@reduxjs/toolkit'
const initialState = {
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) => {
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関数を使用して、その状態へのすべての更新を処理するようにストアに指示します。
- TypeScript
- JavaScript
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
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export const store = configureStore({
reducer: {
counter: counterReducer,
},
})
ReactコンポーネントでReduxの状態とアクションを使用する
React-Reduxフックを使用して、ReactコンポーネントがReduxストアと対話できるようにします。useSelector
でストアからデータを読み取り、useDispatch
を使用してアクションをディスパッチできます。<Counter>
コンポーネントを含むsrc/features/counter/Counter.js
ファイルを作成し、そのコンポーネントをApp.js
にインポートして<App>
内にレンダリングします。
- TypeScript
- JavaScript
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>
)
}
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
export function Counter() {
const count = useSelector((state) => 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とアクションクリエーターをエクスポートします
- 文字列名、初期状態、および名前付きreducer関数を使用して
- ReactコンポーネントでReact-Redux
useSelector/useDispatch
フックを使用するuseSelector
フックを使用してストアからデータを読み取るuseDispatch
フックでdispatch
関数を取得し、必要に応じてアクションをディスパッチします
完全なカウンターアプリの例
ここで示されているカウンターの例アプリも
実行中のCodeSandboxとしての完全なカウンターアプリケーションは次のとおりです
次のステップ
Reduxコアドキュメントの「Redux Essentials」および「Redux Fundamentals」チュートリアルを読むことをお勧めします。Reduxのしくみ、Redux Toolkitの機能、および正しく使用する方法を完全に理解できます。