Kosaku Kurino

Kosaku Kurino

【React】redux-actionsでreducerとactionsをすっきりさせよう

redux-actionsとは

ReactとReduxを利用する際、必ず必要となるActionとReducerをflux standard actionに準じた形で簡潔にかける便利なライブラリ。

詳しくはこちら↓ https://redux-actions.js.org/

redux-actionsを利用することで、Action**とReducerをすっきりさせましょう!

対象者

ReactとReduxを使ったことがある方

手順

ComponentとContainerの準備

Componentを作成します。 handleClickOnehandleClickTwoという関数を発火させるボタンを設置しましょう。

import React from 'react'

const Component = (props) => {
  return (
    <div>
      <p>Hello World</p>
      <input type="button" value="One Button" onClick={props.handleClickOne} />
      <input type="button" value="Two Button" onClick={() => props.handleClickTwo('hello')} />
    </div>
  )
}

export default Component

Containerを作成します。 handleClickOnehandleClickTwoをActionsのclickOneclickTwoと繋げます。

import { connect } from 'react-redux'
import Component from './Component'
import { Actions } from './Action' // Actionsは後で作成します。

const mapDispatchToProps = (dispatch) => {
  return {
    handleClickOne: () => dispatch(Actions.clickOne()),
    handleClickTwo: (text) => dispatch(Actions.clickTwo(text)),
  }

const mapStateToProps = (state) => {
  return state
}

export default connect(mapStateToProps, mapDispatchToProps)(Component)

redux-actionsでreducerとactionsを作る

まずactionsからみていきましょう。 actionsにはclickOneclickTwoを定義しないといけません。

redux-actionsを使わない書き方はこちら

export const Actions = {
  clickOne () {
    return {
      type: 'CLICK_ONE',
    }
  },
  clickTwo (value) {
    return {
      type: 'CLICK_TWO',
      payload: value,
    }
  },
}

redux-actionsを利用した書き方はこちら

import { createActions } from 'redux-actions'

export const Actions = createActions(
  {
    CLICK_TWO: (args) => (args)
  },
  'CLICK_ONE',
)

どちらの書き方もおなじActionを定義しています。 redux-actionsを利用することでかなりすっきりかけることがわかると思います。

引数が必要なActionはCLICK_TWO: (args) => (args)のように書けばよいです。 引数はpayloadに入ります。

{
  type: 'CLICK_TWO',
  payload: args,
}

次は、reducerをみていきましょう。 reducerにはCLICK_ONECLICK_TWOが発火したときの、ステート更新を書かないといけません。

redux-actionsを使わない書き方はこちら


// 初期値
const initialState = {
  text: null,
}

export const Reducer = (state=initialState, action) => {
  switch (action.type) {
    case 'CLICK_ONE':
      return {
        ...state,
      }

    case 'CLICK_TWO':
      return {
        ...state,
        text: action.payload
      }

    default:
      return state
  }
}

redux-actionsを利用した書き方はこちら

import { handleActions } from 'redux-actions'
import { Actions } from './Actions' //作成したActionsを読込

const initialState = { 
    text: null,
}

export const Reducer = handleActions({
  [Actions.clickOne]: (state, action) => ({
    ...state
  }),
  [Actions.clickTwo]: (state, action) => ({
    ...state,
    text: action.payload,
  }),
}, initialState)

どちらの書き方もおなじReducerを定義しています。 この程度の数だとあまり変わりないように見えますが、Actionが増えればredux-actionsを使った方がよりすっきりするのがわかります。

引数はaction.payloadで取得できます。

[Actions.clickOne]: (state, action) => ({
  ...state,
  text: action.payload,
}),

後は通常通り、storeを作成し、Reducerを登録し、Providerタグの作ったstoreを登録すれば動きます。

#参考 https://github.com/redux-utilities/flux-standard-action https://redux-actions.js.org/