Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redux: Calling store.getState() in a reducer function, is that an anti pattern?

I'm wondering, sometimes I have a reducer that needs information from another reducer. For example I have this reducer:

import * as ActionTypes from '../actions/action_type_constants';
import KeyCode from 'keycode.js/index';
import {store} from "../index";
import {mod} from "../pure_functions";

export function selectedCompletion(state = 0, action) {
  if (action.type === ActionTypes.arrowKeyPressed) {
    const completionsLength = store.getState().completions.data.length;
    if (action.keyCode === KeyCode.UP) {
      return mod(state - 1, completionsLength);
    } else if (action.keyCode === KeyCode.DOWN) {
      return mod(state + 1, completionsLength);
    }
  }
  return state;
}

I do call store.getState at the second line of the function, because otherwise I can not determine the index correctly.

I could probably refactor this and the other reducer, so that it becomes one big reducer, but for readability I would prefer this option.

I'm not sure if I would get somehow into problems if I use this pattern of calling store.getState() in a reducer.

like image 557
Kasper Avatar asked Jul 23 '16 18:07

Kasper


People also ask

What are Redux patterns?

Redux is a pattern and library for managing and updating application state, using events called "actions". It serves as a centralized store for state that needs to be used across your entire application, with rules ensuring that the state can only be updated in a predictable fashion.

What pattern for single file logic is recommended by Redux?

Within a given feature folder, the Redux logic for that feature should be written as a single "slice" file, preferably using the Redux Toolkit createSlice API. (This is also known as the "ducks" pattern).

What is the main purpose of a reducer function in Redux?

Introduction. In Redux, a reducer is a pure function that takes an action and the previous state of the application and returns the new state. The action describes what happened and it is the reducer's job to return the new state based on that action.

What happens when you try to dispatch an action within a reducer?

Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.


1 Answers

Yes, this is absolutely an anti-pattern. Reducer functions should be "pure", and only based on their direct inputs (the current state and the action).

The Redux FAQ discusses this kind of issue, in the FAQ on sharing state between reducers. Basically, you should either write some custom reducer logic that passes down the additional information needed, or put more information into your action.

I also wrote a section for the Redux docs called Structuring Reducers, which discusses a number of important concepts related to reducer logic. I'd encourage you to read through that.

like image 198
markerikson Avatar answered Nov 07 '22 07:11

markerikson