3

I am new to redux and react, and I read in Dan Abrahamov's post(https://stackoverflow.com/a/35675304/8643584) that reducers should be pure and affect as little as possible, I want to implement radio button kind of logic, and it looks to me logical to implement this kind of logic inside a reducer, is it acceptable?

I right now implemented the logic, that changes the state for 3 variables at one reducer action, other way I can think of, is making reducers to change 1 value at time, then subscribing for changes, and then within the subscription calling the other 2 reducers to change their value accordingly.

my current logic:

const initialState = {
    toggleCreate: false
    toggleUpdate: false,
    toggleDelete: false,
};
const reductionReducer = (state = initialState, action) =>{
    switch (action.type) {
        case "CRUDBAR_CREATE":
            return {
                toggleCreate: !state.toggleCreate,
                toggleUpdate: false,
                toggleDelete: false,
            };
        case "CRUDBAR_UPDATE":
            return {
                toggleCreate: false,
                toggleUpdate: !state.toggleUpdate,
                toggleDelete: false, 
            };
        case "CRUDBAR_DELETE":
            return {
                toggleCreate: false,
                toggleUpdate: false,
                toggleDelete: !state.toggleDelete, 
            };
        default:
            return state;
    }
};
export default categoryReducer;

the other way, which I suspect might be the acceptable one:

const initialState = {
    toggleCreate: false
    toggleUpdate: false,
    toggleDelete: false,
};
const reductionReducer = (state = initialState, action) =>{
    switch (action.type) {
        case "CRUDBAR_CREATE":
            return {
                toggleCreate: !state.toggleCreate,
                toggleUpdate: state.toggleUpdate,
                toggleDelete: state.toggleDelete,
            };
        case "CRUDBAR_UPDATE":
            return {
                toggleCreate: state.toggleCreate,
                toggleUpdate: !state.toggleUpdate,
                toggleDelete: state.toggleDelete,
            };
        case "CRUDBAR_DELETE":
            return {
                toggleCreate: state.toggleCreate,
                toggleUpdate: state.toggleUpdate,
                toggleDelete: !state.toggleDelete, 
            };
        default:
            return state;
    }
};
export default categoryReducer;

I expect other developers to be able to contribute to my app without falling into holes, they never expected to. So I ask the more experienced developers for insight, thank you.

Efim Rozovsky
  • 363
  • 3
  • 11

4 Answers4

4

Yes, this is a completely legitimate use case for Redux. You definitely can change multiple variables with one action. I would even argue that this is one of the strongest points for using Redux. Because Redux allows you to group one user action to the multiple effects it has on you application in a clear way.

Sgiath
  • 360
  • 2
  • 8
1

Yes, updating several parts of the state for a single action is completely normal in Redux.

In addition to the other answers I want to note that this functionality:

        return {
            toggleCreate: !state.toggleCreate,
            toggleUpdate: false,
            toggleDelete: false,
        };

Does not implement radio button like functionality, in particular it can lead to a situation where all three are false. With radio buttons, you can't toggle a choice off, you have to choose another one. So it would have to set toggleCreate to true.

Also, 'toggle' is a strange name for a variable, but I don't know the use case.

As another option, you could instead store the current choice in a single variable:

    case "CRUDBAR_CREATE":
        return {
            toggleChoice: "create"
        };

That way it is immediately obvious that the variable can't have two choices activated. You could enforce the string to be one of three possibilities by using Typescript.

RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79
1

I tend to prefere writing down less code, so I would skip the multiple actions and multiple values thing. A radio button logic only needs to store one value, the one that's active. And you only need one action to update it. You can either store it as a string or an object containing one key (and value to true), depending how you check for the value on the component.

jorbuedo
  • 2,041
  • 1
  • 8
  • 20
0

The first example is correct (only one toggle should be enabled, the others should be false). On the second example:

case "CRUDBAR_DELETE":
  return {
    toggleCreate: state.toggleCreate,
    toggleUpdate: state.toggleUpdate,
    toggleDelete: !state.toggleDelete, 
  }

This could cause both toggleCreate and toggleDelete to be selected, because it's keeping them with their previous state (imagine checkboxes, instead of radio buttons):

(o) Create
( ) Delete
( ) Update

# Click on update:

(o) Create ( => state.toggleCreate)
( ) Delete ( => state.toggleDelete)
(o) Update ( => !state.toggleUpdate)

This is because state = initialState only happens the very first time if the reducer state is not defined. Usually, it will return the current state.

Yuan-Hao Chiang
  • 2,484
  • 9
  • 20