reduxで使われるワードの意味
State:アプリケーションの状態
Store:アプリケーション内の全てのstateを保持している場所
Action:アプリケーションのstateをどのように変更するかの注文表みたいな役割
Action creator: Actionのtype(注文表)を生成する関数
Reducer:Actionのtype(注文表)に応じてstateを変化させる関数
reduxルール
- Storeはアプリケーションに1つのみ存在する。
- Stateを変更できるのは、Reducerのみ。// storeのstateはグローバル変数なので、どこの処理でデータが描き変わったか
- ReducerはStore内のStateを、action typeに応じて新しいStateに更新する
- Reducerは常に同じ結果を返す
手順
step1 Redux ToolkitとReact-Reduxをインストール
npm install @reduxjs/toolkit react-redux
step2 storeを作成
自動的に、Redux DevTools extensionと連携してくれます。
app/store.js
import { configureStore } from '@reduxjs/toolkit'
export default configureStore({
reducer: {}
})
step3 ReactのRootコンポーネントをProviderコンポーネントでラップする
step2で定義したstoreをProviderコンポーネントのstoreにpropsで渡すと、storeにreduxが用意しているAPIを使うとstoreの要素にアクセスすることができます。
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')
)
step4 createSliceでreducer関数と、action creator関数を定義
features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit'
export const counterSlice = createSlice({
// action typeのprefix
// 一意である必要があるため名前がぶつかることを防ぐ
name: 'counter',
// 初期値
initialState: {
value: 0
},
// reducer
// dispatchで送られてきたaction creatorをもとに下記に定義されているreducerが実行され、storeのstateを書き換える
reducers: {
increment: state => {
state.value += 1
},
decrement: state => {
state.value -= 1
},
incrementByAmount: (state, action) => {
state.value += action.payload
}
}
})
// action creator
export const { increment, decrement, incrementByAmount } = counterSlice.actions
export default counterSlice.reducer
step5 storeにstep4で生成したreducerを追加する
app/store.js
import { configureStore } from '@reduxjs/toolkit'
import counterReducer from '../features/counter/counterSlice'
export default configureStore({
reducer: {
counter: counterReducer
}
})
step6 コンポーネントで呼び出してみる
features/counter/Counter.js
import React from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { decrement, increment } from './counterSlice'
import styles from './Counter.module.css'
export function Counter() {
// stateは、storeのstateでcounterは、storeのreducerのkeyが入って、valueは、createSliceのinitialValueが参照されます。
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>
)
}
以上