ReactでReduxデータの操作をするとき、componentファイルに描画コードとデータ操作コードを書いても良いのですが、Reduxと描画のテストを別々にできない、という欠点もあるので、描画はComponentファイルに書いてReduxのデータ関連はContainerファイルに書く、ということをします。下記がContainerファイルの例です。
import { connect, ConnectedComponentClass } from 'react-redux'
import { Dispatch, AnyAction } from 'redux'
const mapStateToProps: (state: RooteState) => HogeContainerStateObj = (state: RooteState) => {
return {
hogeState: state.hogeState
}
}
const mapDispatchToProps = ( dispatch: Dispatch<AnyAction> ) => {
return {
activateHogeApi: (): void => {
dispatch(postHogeApi())
}
}
}
const HogeContainer = connect( mapStateToProps, mapDispatchToProps )(HogeComponent)
export default HogeContainer
これは何をやっているかといいますと、HogeComponent側で必要となるReduxのStateとActionをPropsとして、HogeComponentに渡しているのです。渡し方としては、mapStateToProps
にStateを、 mapDispatchToProps
にActionをそれぞれ持ち、それらを connect
を使用して、HogeComponentに渡しています。HogeComponentでconsole.logでPropsを見ると、hogeState
と activateHogeApi
が渡ってきていると思います。
ContainerはこのようにconnectしてComponentにReduxのデータを渡しています。これをHooksで書き換えると以下のようになります。
import React, { useCallback } from 'react'
import { useSelector, useDispatch } from 'react-redux'
const mapStateToProps = () => {
const hogeState = useSelector<RooteState, HogeState>(
(state: RooteState) => state.hogeState
)
return { hogeState }
}
const mapDispatchToProps = () => {
const dispatch = useDispatch()
const activateHogeApi = useCallback((): void => {
dispatch(postHogeApi())
}, [dispatch])
return { activateHogeApi }
}
const HogeContainer = (props): JSX.Element => {
const _props = { ...mapStateToProps(), ...mapDispatchToProps(), ...props }
return <HogeComponent {..._props} />
}
export default HogeContainer
やろうとしていることはHogeComponentにReduxの必要なデータを渡すということなのでそこは変わりませんが、書き方は少し違います。React Hooksには useState
useReducer
といったHooksAPIがあり、頭に use
がつく特徴を持っています。
そして今回でいうと、 useSelector
と useDispatch
、 useCallback
を使用しています。詳細はググってもらえるとわかるのですが、本当に簡単にいうと、useSelector
はStateをみる、 useDispatch
はdispatch使う、 useCallback
はメソッド呼び出す、です。
結局、それぞれの変数にStateとActionをreturnしているだけです。そしてここで違ってくるのが、HogeContainerをJSX扱いする、ということです。どういうことかというと、 connect
を使用していた部分を、普通にHogeComponentにデータを渡して、そのHogeComponentをHogeContainerというJSXで使用するだけ、です。
正直ここに書いてことを読むだけではHooksにわざわざ書き換える意味がないのでは?と思うかもしれません。しかし使用してみると、データの更新やファイルの扱いやすさ、というものが見えてくるので、新しく作るComponentにはReact Hooksを使用してみてください。