D
D
Dmitry2020-05-02 12:07:40
React
Dmitry, 2020-05-02 12:07:40

What is the point of using actions, actionCreators etc. in react-redux?

The generally accepted approach implies that if I want to change something in the store state, I have to do 4 actions:

1) Create a constant for the action (it is naturally inconvenient to send and process strings)
2) Create an action creator
3) Create a function for mapDispatchToProps in each component , which calls the creator
4) Write the state change logic in the reducer

Why is everything so complicated if in the vast majority of cases (in my experience) it is still one type, one creator and one logic for processing it in the reducer? Why not simplify? For example, we create an actions.js file (Or many files with a logical breakdown), in which we write functions that immediately change the state

// actions.js
export const setCategories = (payload, setState, currentState) => setState({ categories: payload })
export const addCategory = (payload, setState, currentState) => setState({ categories: [...currentState.category, payload] })


and to make it all work, we create a couple of universal functions

1) getActions , which will automatically collect all exports for mapDispatchToProps from actions.js, it might look something like this

// actionsDispatcher.js
import * as actions from 'actions'
const getActions = (dispatch, ownProps) => {
  Object.keys(actions).forEach(actionName => {
    const fn = actions[actionName]
    actions[actionName] = payload => dispatch({ action: fn, payload, type: _.toSnakeCase(actionName) })
  }
  return actions
}


That is, it will send not only data to the reducer, but also the processing function itself. And in the components, it is enough for us to write

const mapDispatchToProps = getActions

in order to get access to any action through props

2) setState which will work similarly to the React setState used in components, but for the storage state. I will not describe the code, in any case it is not very complicated, the main thing is to make the state spreading automatic.

and in the reducer there will be just a line

function rootReducer(state = initialState, action) {
  if (typeof action.action === 'function') {
    return action.action(action.payload, setState, state)
  } else if (action.type === '...') {
    // здесь обычный подход
  }
}


What is categorically wrong in such an approach? Abramov wrote somewhere that such a scheme would be bad if one action creator is used for several reducers. But I don't understand how it is? In order for a reducer to process an action, it must have its own type, right? Or is it assumed that one creator can be called with a different action type And be processed differently in different reducers, respectively? Then it makes some sense, but how common is this situation. And in any case, as follows from my code for the reducer, this situation can be handled and in some cases coded directly in the reducer, depending on the type. For example, this can be done by setting in actions for this particular action not a function, but an object with the type property, and writing code already in reducers.

In my opinion, this approach will be much more convenient and at the same time all the advantages and possibilities of the generally accepted approach will be preserved.

Thanks for the clarifications.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry, 2020-05-02
@dimoff66

Bare Redux is a low-level constructor and set of guidelines. Any project that uses redux sooner or later starts using self-written or third-party (like redux-toolkit) wrapper libraries over redux in order to reduce the number of boilerplate and make life easier for itself.
If you understand and accept your approach, whatever it may be, with all its pluses and minuses, and it works for you, use it to your health. It may not suit others.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question