LoginSignup
26
25

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-12-06

redux-actionsとは

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

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

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

対象者

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

手順

ComponentとContainerの準備

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

Component.js
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と繋げます。

Container.js
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を使わない書き方はこちら

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

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

Action.js
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を使わない書き方はこちら

Reducer.js

// 初期値
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を利用した書き方はこちら

Reducer.js
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/

26
25
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
26
25