Deng  Zhebin
Deng Zhebin

Reputation: 1262

action type exported by redux-actions library no way be re-used

Normally we will do following thing to define a set redux action&reducer with redux-actions library

export const {
  open,
  close,
  send
} = createActions({
  OPEN: payload => ({
    payload
  }),
  CLOSE: payload => ({
    payload
  }),
  SEND: payload => ({
    payload,
  })
});


export const combinedReducer = createActions({
  [open]: (state, action) => { /*you do someting*/ },
  [close]: (state, action) => { /*you do someting*/ },
  [send]: (state, action) => { /*you do someting*/ }
});



/*in some where , we are going to handle the a triggered action type respectively in a switch statement.
but we have to use string concatenation to make the switch express strict equal pass , any graceful solution ? */


switch (action.type) {
  case open + "":
    //do someting
    break;
  case close + "":
    //do someting
    break;
  case send + "":
    //do someting
    break;
}

Variables open , close , send generated above are actually function type and their toString() are overrided by redux-action lib to export a string like "OPEN","CLOSE","send"

however if we would like to reuse these action type inside switch statement, we have to concatenate with '' in such an awkward way just to pass the switch express.

Are any graceful ways out there to avoid this kind of stupid code when dealing with switch statement parse which enforces strict equal compare ===

thanks in advance.

Upvotes: 0

Views: 245

Answers (2)

Simon Dell
Simon Dell

Reputation: 638

I may have misunderstood your question, so my previous answer might not get close to what you want.

Another technique I've used, employing both createActions() and switch/case looked like this:

import { createAction } from 'redux-actions'

// your action creators
export const myAction = createAction('ACTION_TYPE')

// your store slice/reducers
const defaultSliceState = {}
export const slice = (state = defaultSliceState, action) => {
    switch(action.type) {
        case myAction().type:
            return Object.assign({}, state, { someValue: action.payload })
    }
}

UPDATE

If you need to enforce strict equality, and don't feel so concerned about following typical/cute/neat patterns, you can use this:

// your store slice/reducers
const ACTION_TYPE_1 = 'ACTION_TYPE_1'
const ACTION_TYPE_2 = 'ACTION_TYPE_2'
// add your action creators here: const myAction = createAction(ACTION_TYPE)
// ...

const defaultSliceState = {}
export const slice = (state = defaultSliceState, action) => {
    switch(true) {
        case action.type === ACTION_TYPE_1:
            return Object.assign({}, state, { someValue: action.payload })
        case action.type === ACTION_TYPE_2:
            return Object.assign({}, state, { otherValue: doSomething(action.payload) })
    }
}

... but you don't even need to do this if your ONLY concern is strict equality. By a little experiment, I found switch/case already uses strict equality checks.

function match (arg) {
  switch(arg) {
    case 1: return "matched num"
    case '1': return "matched str"
  }
}

match(1) // -> matched num
match('1') // -> matched str

Upvotes: 1

Simon Dell
Simon Dell

Reputation: 638

One way uses the handleAction or handleActions functions, also provided by redux-actions. Rather than write a long switch statement with [action.type] cases, you instead map your action creators to reducers using these functions.

This resembles how I like to do it:

import { createAction, handleActions } from 'redux-actions'

// your action creators
export const myAction = createAction('ACTION_TYPE`)

// your reducer (this example doesn't do anything useful)
const myReducer = (state, action) => Object.assign({}, state, { someValue: action.payload })

const sliceDefaultValue = {}
export const slice = handleActions({
    [myAction]: myReducer
}, sliceDefaultValue)

The handleAction function documentation lives here: https://redux-actions.js.org/api/handleaction.

Upvotes: 0

Related Questions