useDispatch、Providerの役割
はじめに
Reduxの公式ドキュメントに沿って概要を押さえつつ、気になった部分を深掘って整理しています。
本記事では 、Reduxのサンプルアプリを通してuseDispatch、Providerの役割についてまとめていきます。
useDispatch
ストアにアクセスせずにアクションをディスパッチすることができます。
Reduxストアがある場合、アクションクリエーターを用いてアクションをディスパッチできます。
(アクションクリエーターとは、アクションオブジェクトを生成して返す関数のことを指します。)
store.dispatch(increment())
ストア自体に直接アクセスできない場合でも、ディスパッチメソッドにアクセスしたいケースもあります。
その様の場合には、useDispatchを使用します。
import React from 'react'; import { useDispatch } from 'react-redux'; import { increment } from './actions'; function Counter() { const dispatch = useDispatch(); return ( <button onClick={() => dispatch(increment())}> カウントアップ </button> ); } export default Counter;
useDispatchフックを使用すると、コンポーネント内部で直接dispatch関数にアクセスすることができます。
したがってボタンがクリックされたときに、incrementアクションクリエーターが呼び出され、その結果生成されたアクションがdispatchされます。
Reduxストアで管理するべき状態
アプリのすべての状態を常にReduxストアに入れる必要はありません。
アプリ全体で必要とされるグローバルな状態はReduxストアに入れるべきです。
ただし、一部の場所でしか必要とされない状態はコンポーネントの状態として保持すべきです。
例
下記はカウンターに加算する数値を調整するテキストフォームの実装例です。
// features/counter/Counter.js const [incrementAmount, setIncrementAmount] = useState('2') return ( <div> <input value={incrementAmount} onChange={e => setIncrementAmount(e.target.value)} /> <button onClick={() => dispatch(incrementByAmount(Number(incrementAmount) || 0))} > Add Amount </button> <button onClick={() => dispatch(incrementAsync(Number(incrementAmount) || 0))} > Add Async </button> </div> )
上記で扱っている数値を表す文字列は、inputのonChangeハンドラでアクションをディスパッチし、リデューサーで保持することでReduxストアに保存することが可能ですが、使用されるのは
React + Reduxアプリでは、グローバルな状態はReduxストアに、ローカルな状態はReactコンポーネントに保持すべきです。
StoreのProvider
ReactコンポーネントがどのようにReduxのストアと通信して
useSelectorやuseDispatchフックがどのようにストアにアクセスするのかについて解説します。
コンポーネント
useSelectorやuseDispatchのフックは<Provider>コンポーネント
を通じて特定のReduxストアを見つけます。
下記は、アプリケーションのエントリーポイントであるindex.jsファイルのコードです。
// src/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' import * as serviceWorker from './serviceWorker' ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') )
Reactでは、renderメソッドを使ってルートとなる
useSelectorやuseDispatchといったフックが適切に機能するためには、
ストアは下記の通りapp/store.js
で作成しているので、src/index.js
でインポートします。
// src/app/store.js import { configureStore } from '@reduxjs/toolkit'; import counterReducer from '../features/counter/counterSlice'; export const store = configureStore({ reducer: { counter: counterReducer, }, });
そして、アプリケーション全体を
<Provider store={store}>
このように設定することで、useSelectorやuseDispatchフックを使う全てのReactコンポーネントが、
これがReactとReduxの橋渡しを行う
参考
続く…
コメント
本記事の内容は以上になります!
書籍の続きのアウトプットも随時更新したいと思います。
プログラミングスクールのご紹介 (卒業生より)
お世話になったプログラミングスクールであるRUNTEQです♪
こちらのリンクを経由すると1万円引きになります。
RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。
もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。