LoginSignup
8
8

More than 3 years have passed since last update.

React HooksでContainerってどうやって作るの?

Posted at

ReactでReduxデータの操作をするとき、componentファイルに描画コードとデータ操作コードを書いても良いのですが、Reduxと描画のテストを別々にできない、という欠点もあるので、描画はComponentファイルに書いてReduxのデータ関連はContainerファイルに書く、ということをします。下記がContainerファイルの例です。

HogeContainer.ts
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を見ると、hogeStateactivateHogeApiが渡ってきていると思います。

ContainerはこのようにconnectしてComponentにReduxのデータを渡しています。これをHooksで書き換えると以下のようになります。

HogeContainer.tsx
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 がつく特徴を持っています。

そして今回でいうと、 useSelectoruseDispatchuseCallback を使用しています。詳細はググってもらえるとわかるのですが、本当に簡単にいうと、useSelector はStateをみる、 useDispatch はdispatch使う、 useCallback はメソッド呼び出す、です。

結局、それぞれの変数にStateとActionをreturnしているだけです。そしてここで違ってくるのが、HogeContainerをJSX扱いする、ということです。どういうことかというと、 connect を使用していた部分を、普通にHogeComponentにデータを渡して、そのHogeComponentをHogeContainerというJSXで使用するだけ、です。

正直ここに書いてことを読むだけではHooksにわざわざ書き換える意味がないのでは?と思うかもしれません。しかし使用してみると、データの更新やファイルの扱いやすさ、というものが見えてくるので、新しく作るComponentにはReact Hooksを使用してみてください。

8
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8