What is the meaning of actions and action types in React-redux?

孤街醉人 提交于 2021-01-28 08:33:55

问题


Now if i want to change value in store i should do following steps:

  1. Go to constants/actionTypes file, create a line with action type
  2. Go to actions and create action function
  3. In each component where i use it i should create a function for mapDispatchToProps
  4. In reducer i should write a logic of changing

Whats the point of such complexity? Will it be wrong if i will do just one file with actions which will change the state? For example:

// actions.js

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

To make it work i can create just couple of universal functions for all projects

1) getActions, which authomaticly collects all exports from actions.js and provide them to mapDispatchToProps, so in all components we could just write

const mapDispatchToProps = getActions

code of it can be something like

// 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
}

which means we pass to dispatch the function of action from actions.js

2) setState which will work similary to react function, but for redux state

then in reducer function we just right

function rootReducer(state = initialState, action) {
  if (action.action) {
    action.action(action.payload, setState, state)
  } 

  // here we make it extandable for ordinary way if required
  if (action.type === '...') {
    // ...  
  }

}

and nothing else...

So the question is whats wrong in such approach that will require for coder just write a function in one file 'actions.js' and call it from any component as props.someActionName(someParams) instead of changing 4 differents files?

Thank you


回答1:


Redux is supposed to make complex requirements easier to implement but if you have simple requirements then it makes implementing these requirements more complicated.

The motivation mentions CQRS(Command Query Responsibility Segregation) that separates how you read from store (in redux with selectors and I'm a big fan of reselect) with how you write to it (with action and reducers).

The actions and reducers are the command (write) part of CQRS and is event sourcing, redux is sometimes referred to as an event store. This enables you to add or remove handlers (reducers or middle ware) for your events (actions) that can update the store, dispatch other events (=actions), do asynchronous stuff, write to local storage.

If you need to do all these things in one function (async fetch, write to local storage, call other functions (dispatch other actions),...) then that function becomes unmanageable.

Even if the function only calls other functions then it still needs to know the entire process of certain action. But if (for example) you had a local storage middleware that would write to storage on certain actions then no other code needs to know how or when it's called. So when logic of writing to local storage changes it is limited to the local storage middle ware.

This is the advantage of handlers (reducers, middleware) listening to events (actions), the handler only needs to know about a small portion of the process, not the entire process.

With event resourcing we also know why the state has a certain value instead of only knowing what the state is, the article states:

However there are times when we don't just want to see where we are, we also want to know how we got there.

Another big advantage of an event store is that you can re create the data by playing back the events. All this is excellently done with redux def tools.

Here is a great book on React with Redux.




回答2:


Conventional-redux is a:

Library for small and medium react applications, it wraps the react-redux and provides API based on convention over configuration pattern without breaking redux compatibility.

You simply define an interactor:

 class CounterInteractor {
  // initial state
  defaultState() {
    return 0;
  }

  // actions:
  doubleAsync() {
    setTimeout(() => { this.dispatch('counter:double') }, 500)
  }

  // reduce methods:
  onIncrement() {
    return this.state + 1;
  }

  onDouble() {
    return this.state * 2;
  }
}

And dispatch actions to that interactor from your connected component component. That's it!



来源:https://stackoverflow.com/questions/61556343/what-is-the-meaning-of-actions-and-action-types-in-react-redux

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!