Help us understand the problem. What is going on with this article?

爆速Redux ES6だけで現代風コードダイエット

alt

redux素晴らしい

パフォーマンス良し、テスト良し、デバッグ良し、エコシステム良し。
私はreact nativeの人なのですが、redux-persistを使いたいために、2019年でもreduxを使い続けると思います。

ただreduxにも弱点があります。学習コストの高さと、記述量の多さです。
そのため、reduxの記述量を減らすためのライブラリが数多く生み出されてきました。
redux-actions, redux-sauce, etc...

時代はES6へ変わりました、現代風のreduxの書き方で記述量を半分にダイエットしましょう。

完成品は以下のurlにあります。
https://github.com/soniczsonic/reduxtuto/tree/master

一般的なreduxの書き方

userの名前を扱うreduxです。

// redux.js
export const deleteName = () => ({  
  type: 'DELETE_NAME',
  name: ''
});

export const setName = name => ({  
  type: 'ADD_NAME',
  name: name,
});

INITIAL_STATE = {
  name: 'Nanasi'
}

export default (state = INITIAL_STATE, action) => {  
  switch (action.type) {
    case 'ADD_NAME':
      return {...state, name: action.name}
    case 'DELETE_NAME':
      return {...state, name: ''}
    default:
      return state;
  }
}

よくあるswitch文です。記述量が多いですね。
ここで目をつけるのが一箇所。

そもそもAcrion creator いらないのでは

そう、今回はactionを直接viewに書き込みます。意外にも、スッキリしたコードになります。
(ただし、この書き方はredux-thunkとは併用できません。redux-sagaか、redux-observableなどを使いましょう)

まずjsのオブジェクトについておさらい

  1. オブジェクトリテラル。 オブジェクトリテラルとは{}で囲むとオブジェクトを作ることができる構文です。new classとだいたい同じです。 つまり、
obj = {name: 'kabaya' sayName: () => console.log('kabaya desu.')}
と書けます。
obj.nameobj.sayNameを実行してみましょう。

2.hasOwnProperty
objectが特定のkeyを持っているかを真偽値で返します。

obj.hasOwnProperty('name') // true
obj.hasOwnProperty('sex') // false

以上のことを後で使うので覚えておいてください。

reduxをダイエット。

まず用意するのは以下のcreateReducer関数です。純粋なjsで作ったスニペットです。
jsのカリー化を使ってfunction fucoryと呼ばれるものを作ります。
つまり、functinonを作成するためのfunctionを作ります。

// createReducer.js
export function createReducer(initialState, actionHandlers) {
  return function reducer(state = initialState, action) {
    if (actionHandlers.hasOwnProperty(action.type)) {
      return actionHandlers[action.type](state, action)
    } else {
      return state
    }
  }
}

上のcreateReducer関数を使うと、reduxが以下のように書けます。

// superUserRedux.js
import createReducer from './createReducer'

INITIAL_STATE = {
  name: 'Super User',
  age: 16
}

const actions = {
  SET_SUPER_USER_NAME: (state, action) => ({...state, name: action.name, age: action.age}),
  DELETE_SUPER_USER: (state, action) => ({...state, name: '', age: 0})
}

export default createReducer(INITIAL_STATE, actions)

type: 'ACTION'と直接書き込みます。

// heme.js
const mapDispatchToProps = dispatch => ({
  // actionCreatorをimportした場合
  setName: (name) => dispatch(setName(name)),
  deleteName: () => dispatch(deleteName()),
 // actionCreatorをimportしない場合。
  setSuperUser: (name, age) => dispatch({type: 'SET_SUPER_USER_NAME', name, age}),
  deleteSuperUser: () => dispatch({type: 'DELETE_SUPER_USER'}),
})

注意

dispatchの中のactionのプロパティと、reducerの引数の名前は一致している必要があります。
つまり、

setSuperUser: (name1, age) => dispatch({type: 'SET_SUPER_USER_NAME', name1, age})

とした場合は、
reducerの方でも

SET_SUPER_USER_NAME: (state, action) => ({...state, name: action.name1, age: action.age})

とnameをname1に変えてあげる必要があります。
なぜかというと、dispatch()の引数は、reducerにactionという形で渡されるからです。
つまり、
SET_SUPER_USER_NAME: (state, action)のactionの中身は{type: 'SET_SUPER_USER_NAME', name, age}ということです。

さらに簡潔に

mapDispatchToProopsのショートハンドを使いましょう。
実は、dispatchを使わずに、action creatorを直接、mapDispatchToPropsに書き込めます。

// heme.js
const mapDispatchToProps = {
  // actionCreatorをimportした場合
  setName,
  deleteName,
 // actionCreatorをimportしない場合。
  setSuperUser: (name, age) => ({type: 'SET_SUPER_USER_NAME', name, age}),
  deleteSuperUser: () => ({type: 'DELETE_SUPER_USER'}),
}

ES6の力は偉大ですね。
純粋なjsだけでこれほどreduxの記述量を減らすことができました。

参考url
https://medium.freecodecamp.org/reducing-the-reducer-boilerplate-with-createreducer-86c46a47f3e2

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away