monobyte
monobyte

Reputation: 109

Where to put model specific business logic in a Redux app

I am struggling to understand where I should put some of the functionality in the Redux/React app I'm building.

My scenario is as follows, in my current app I have several JS classes that wrap around specific json objects and provide methods to get various parts of the data transformed based on certain criteria. For instance, they have a getProperty('name') method which looks up the current host environment and returns the correct sub property value for that host.

Where would be the correct place to implement this logic in a Redux app? Ideally I'd want to encapsulate it in a model so other developers don't need to reimplement it in every view.

Would transforming the json data into a class in my data loading action and storing that in the store via reducer be right? If so how could I be sure the state doesn't get mutated via a setter method in the class?

Any help/opinions appreciated.

Upvotes: 6

Views: 3486

Answers (3)

Oliv
Oliv

Reputation: 2423

Lets sum-up the data logic:

  1. Call Action from mapDispatchToProps
  2. Api Call > GET data from web-service (JSON Payload)
  3. Transform or apply some data manipulation in an helpers/ whatever...
  4. Dispatch the action
  5. Add data to your store via the dedicated reducer
  6. mapStateToProps

The loop is closed.

Upvotes: 0

Dan Abramov
Dan Abramov

Reputation: 268265

If you want to transform model data for the view, it is appropriate to do it outside the reducers. Usually we recommend you to export functions that take the current state (and potentially other arguments, like an environment in your case) and return whatever the view needs, for example, getVisibleTodos(state). Such functions can be composed similarly to how you compose reducers, and in fact, we recommend defining them alongside the reducers so you don’t forget to change them when your state shape changes.

The shopping cart example demonstrates this approach. However, recalculating all derived state on every state change is inefficient. This is why we recommend to use a library like Reselect that lets you compose selector functions as dependencies of other selector functions, and memoizes the values so they are not recalculated without necessity.

Please refer to Computing Derived Data for more information about this approach.

Upvotes: 11

takacsmark
takacsmark

Reputation: 4441

Would transforming the json data into a class in my data loading action and storing that in the store via reducer be right?

I think your statement is pretty close, let's add some considerations.

The reducer is not the right place to handle any such logic, since it has to return a new state object only.

Your action creators are supposed to handle actions, thus if some API operation or data manipulation is required, the action creator is the best place to work on it.

When you use the redux thunk middleware you can implement more functional action creators.

if I understand correctly, you already have the logic to handle your JSON data in your js files. I would treat these files as my own proprietary lib or API, if you like. Include that into my action creators and call the appropriate method in your js lib/API to acquire the right data or transformed data from the JSON.

Then I would take this data and pass it to the reducer and put the data into the state.

This way you can reuse the already existing js files, plus you can share the action creators within the team.

If so how could I be sure the state doesn't get mutated via a setter method in the class?

You should not put all the data into your state. Keep the logic in your js files and map your handler functions to actions in your action creators. So if manipulation is needed fire the right action. Only keep the data that's relevant to the app state in your state object.

Upvotes: 0

Related Questions