Redux: Where should processing fetched data logic live in react redux application?

Created on 28 Feb 2016  Â·  4Comments  Â·  Source: reduxjs/redux

I've used react redux at work for a while. One question always comes up and couldn't find exact answer.

I would use redux-thunk to fetch data from server. Often times the data fetched is not exactly the app state, thus additional logic will be needed to process data. (filter, sort, flatten, normallize etc) And there seems at least three ways to do it.

  • in action creator, after fetched data from server, process data and dispatch with processed data
  • dispatch actions with unprocessed data, process in reducer
  • unprocessed data used in actions and reducer, process inside component render

What would be the best and suggested way of solving this issue?

Thanks

question

Most helpful comment

I think @mxstbr gave a good answer.

If the “raw data” is completely irrelevant to the app, process it before dispatching an action. Normalization of JSON response is a good example.

The reducer’s job is to acknowledge the action that happened and store whatever is appropriate. There is no clear guideline on what to store and indeed you can do it in several ways. I would suggest you to try to find a balance between keeping action objects minimal representations of what happened and state objects minimal representations of what’s necessary for rendering right now.

Strive to keep the minimal possible state in the store. If you can compute visibleTodos from todos and visibilityFilter, there is no need to keep visibleTodos in the state.

“Post-processing” such as filtering, sorting, denormalizing should happen before rendering. mapStateToProps() is a good place to do that, and Reselect can help make it more efficient as described in Computing Derived Data.

All 4 comments

Doing that in the component render would mean you reprocess the fetched data every time your component renders, which is not optimal and should be avoided. If the filter is something that the user can change, (e.g. a visibility filter) I'd recommend reselect to process the data.

If that's not the case and you only ever have to process the data once, normalizing it or something, afaik one should generally handle everything in the actions and have your reducer do as little work as possible. The reducer should only _merge_ the action and the old state together to make the new state. This makes your reducer more easily testable, too.

I think @mxstbr gave a good answer.

If the “raw data” is completely irrelevant to the app, process it before dispatching an action. Normalization of JSON response is a good example.

The reducer’s job is to acknowledge the action that happened and store whatever is appropriate. There is no clear guideline on what to store and indeed you can do it in several ways. I would suggest you to try to find a balance between keeping action objects minimal representations of what happened and state objects minimal representations of what’s necessary for rendering right now.

Strive to keep the minimal possible state in the store. If you can compute visibleTodos from todos and visibilityFilter, there is no need to keep visibleTodos in the state.

“Post-processing” such as filtering, sorting, denormalizing should happen before rendering. mapStateToProps() is a good place to do that, and Reselect can help make it more efficient as described in Computing Derived Data.

“Post-processing” such as filtering, sorting, denormalizing should happen before rendering. mapStateToProps() is a good place to do that, and Reselect can help make it more efficient as described in Computing Derived Data.

The issue i am facing with i am using react-dnd and i am depended on the index=itemIndexInArrayInTheState when rendering the items, which is actually the array index of the list i am trying to render as received from the state.
As you suggest to do sort/filter in mapStateToProps() but the problem is that when doing a sorting (if its in mapStateToProps()) with react-dnd i am not receiving the original index that is the same as the state and it will cause total imbalance when doing DnD actions.

There for the only place found suitable (Although not coherent logical) is in the reducer in case of need to change the state and in Actions when when receiving data from fetch request, all and all not having the ability to use mapStateToProps() i need to have duplicate code in the reducer and in the action (although i am importing a helper function that both use it)

Is there any better more convenient way to do so?
thanks

Hi @gaearon, @mxstbr,
I wrote a middleware that listens to the '[X]_DATA_FULFILLED' actions and processes the data before it reaches the reducer, thus keeping the actions and reducers minimal and clean.
Am I misunderstanding something?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rui-ktei picture rui-ktei  Â·  3Comments

amorphius picture amorphius  Â·  3Comments

vslinko picture vslinko  Â·  3Comments

cloudfroster picture cloudfroster  Â·  3Comments

timdorr picture timdorr  Â·  3Comments