John Taylor
John Taylor

Reputation: 779

Is this reducer compliant with the Redux rules?

I'm confused because I don't return state here, only action.payload (code snippet):

case HISTORY_SELECTED:
  return action.payload;

All that reducer code:

import { HISTORY_SELECTED } from '../actions/index';

export default function (state = null, action) {
  switch (action.type) {
    case HISTORY_SELECTED:
      return action.payload;
    default:
      return state;
  }
}

EDIT: Added 3 more cases.

If I understood answer in the right way, also CASE 2, CASE 3 and CASE 4 are ok, yes?

CASE 2 (reducer_note_selected.js)

import { NOTE_SELECTED, DEL_NOTE_SUCCESS } from '../actions/actions';

export default function (state = null, action) {
  switch (action.type) {
    case NOTE_SELECTED:
      return action.payload;
    case DEL_NOTE_SUCCESS:
      return null;
    default:
      return state;
  }
}

CASE 3 (reducer_notes_status_fetch.js - here I'm returning just strings)

 import {
 FETCH_ALL_NOTES_STARTED,
 FETCH_ALL_NOTES_ERROR,
 FETCH_ALL_NOTES_SUCCESS 
} from '../actions/actions';

    export default function (state = {}, action) {
      switch (action.type) {
        case FETCH_ALL_NOTES_STARTED:
          return 'fetching_started';
        case FETCH_ALL_NOTES_ERROR:
          return 'error';
        case FETCH_ALL_NOTES_SUCCESS:
          return 'fetch_all_notes_success';
        default:
          return state;
      }
    }

CASE 4 (reducer_notes_general.js)

import _ from 'lodash';
import { FETCH_ALL_NOTES_SUCCESS, DEL_NOTE_SUCCESS } from '../actions/actions';

export default function (state = {}, action) {
  switch (action.type) {
    case FETCH_ALL_NOTES_SUCCESS:
      return _.mapKeys(action.payload.data, '_id');
    case DEL_NOTE_SUCCESS:
      return _.omit(state, action.payload);
    default:
      return state;
  }
}

Upvotes: 1

Views: 84

Answers (2)

AJ_
AJ_

Reputation: 3987

I disagree with @hindmost, you are replacing the state with your payload value. This is how the react-redux chain works. Hopefully this will clear things up for you.

  • React - Someone clicked a button (any event), ill send this to the action.
  • Action - Got it. I will dispatch the action so the reducer can update the state
  • Reducer - I got the current state and new action. Ill make a new copy of state and pass it along

  • Store - I see the reducer updated the state. Ill make sure all the connected components are aware of the change

  • React-Redux - Got the new data. ill determine if i should update react about these changes. I don't want to bother updating the UI if its not necessary.

  • React - Got the new data in my props from the store. Ill update the UI to reflect the changes.

Upvotes: 3

markerikson
markerikson

Reputation: 67469

Yes, that reducer is absolutely fine conceptually. That simply means that you want to replace whatever the existing state was with the contents of action.payload. Here's a similar example to illustrate the principle:

function todosReducer(todos = [], action) {
    switch(action.type) {
        case LOAD_TODOS: {
            return action.payload.loadedTodos;            
        }
        default: return state;
    }
}

So, in this case, the "new state" that the reducer is returning is the data from the action, as opposed to something that's calculated based on the old state.

The only thing to be careful with is that if your action creator grabbed an existing value from the Redux state and included it in the action, you might wind up not actually changing anything. I helped debug an issue like that in a recent SO question about a reducer "updating while just returning state".

Upvotes: 3

Related Questions