Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to divide the logic between Redux reducers and action creators?

I have some logic that I've put in the reducer which I'm thinking should be possibly put in the Action and passed down?

Is it best practice to put this sort of stuff in the actions or reducer?

Working example here.

Reducer code:

function Card() {   this.card = (Math.random()*4).toFixed(0); }  Card.prototype = {   getRandom: function(){     var card;     //console.log(this.card)     switch (this.card) {       case '1':       card = 'heart';       break;       case '2':       //card = 'diamonds';       card = 'heart'; // weight the odds abit       break;       case '3':       card = 'club';       break;       case '4':       card = 'spade';       break;       default:       card = 'heart';       break;     }     return card;   } }  var dealer = {   deal: function(){     var results = [];     for(var i = 0; i <4; i++){       var card = new Card();       results.push(card.getRandom());     }     console.log(results);     return results;   } }   const initialState = {   count: 0,   data: [] }  function counter (state = initialState, action) {   let count = state.count   switch (action.type) {     case 'increase':       return Object.assign({}, state, {         data: dealer.deal(),         count: state.count+1       })     default:       return state   } } 
like image 863
user3224271 Avatar asked Dec 04 '15 21:12

user3224271


People also ask

How actions and reducers are connected in Redux?

A Redux app really only has one reducer function: the "root reducer" function that you will pass to createStore later on. That one root reducer function is responsible for handling all of the actions that are dispatched, and calculating what the entire new state result should be every time.

How action and reducer are connected?

When you dispatch an action creator it passes the action object to the root reducer. The action object is passed through the entire state tree and any reducers that process the action type consume it.

What is the difference between actions and reducers Redux?

Reducers: As we already know, actions only tell what to do, but they don't tell how to do, so reducers are the pure functions that take the current state and action and return the new state and tell the store how to do.

Can we write logic in reducer?

Most certainly! Reducers should be pure functions, so the logic must be pure as well.


1 Answers

Your reducer must be pure. Currently it is not pure. It calls deal() which calls getRandom() which relies on Math.random() and thus is not pure.

This kind of logic (“generating data”, whether randomized or from user input) should be in the action creator. Action creators don’t need to be pure, and can safely use Math.random(). This action creator would return an action, an object describing the change:

{   type: 'DEAL_CARDS',   cards: ['heart', 'club', 'heart', 'heart'] } 

The reducer would just add (or replace?) this data inside the state.

In general, start with an action object. It should describe the change in such a way that running the reducer with the same action object and the same previous state should return the same next state. This is why reducer cannot contain Math.random() calls—they would break this condition, as they would be random every time. You wouldn't be able to test your reducer.

After you figure out how the action object looks (e.g. like above), you can write the action creator to generate it, and a reducer to transform state and action to the next state. Logic to generate an action resides in action creator, logic to react to it resides in the reducer, reducer must be pure.

Finally, don’t use classes inside the state. They are not serializable as is. You don’t need a Card class. Just use plain objects and arrays.

like image 182
Dan Abramov Avatar answered Sep 25 '22 06:09

Dan Abramov