Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I toggle property in reducer?

I have built a cart app with this reducer in reactjs/redux:

const initialState = {
    items: [],
    cartOpen: false,
    total: 0
}

const Cart = (state = initialState, action) => {
    switch (action.type) {
        case 'ADD_TO_CART':
            let newstate = [...state, action.payload];
            var newTotal = 0;
            newstate.forEach(it => {
                newTotal += it.item.price;
            });
            newstate.total = newTotal;
            newstate.cartOpen =true
            return newstate;

        case 'TOGGLE_CART':
            debugger;
            return !state.cartOpen;

        default:
            return state
    }
}

export default Cart;

I am trying to set the state for the cart ie open but when I check the logs the cart property is updated and not the cartOpen property?

like image 303
bier hier Avatar asked Nov 19 '16 23:11

bier hier


People also ask

How do I change my state from reducer?

Enter combineReducers() It takes an object where each key is a name, each value is a reducer function, and it returns a single reducer that combines them all into a single reducer. So the resulting function takes the whole starting application state, the action to be processed, and returns the new application state.

Can we call action in 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.

How do you write a reducer?

Now that we know what our state structure and our actions look like, it's time to write our first reducer. Reducers are functions that take the current state and an action as arguments, and return a new state result. In other words, (state, action) => newState.

Why do reducers have different state parameters for each component?

Note that each of these reducers is managing its own part of the global state. The state parameter is different for every reducer, and corresponds to the part of the state it manages. This allows us to split up our logic based on features and slices of state, to keep things maintainable.

What is the use of reducer in JavaScript?

Reducers are also often used for changing a single property inside of other reducers. This lesson shows how a type can enter the people reducer, but then the people reducer can use a different type to call the clock reducer and get a value back.

What is the use of reducer in mapper?

Reducer mainly performs some computation operation like addition, filtration, and aggregation. By default, the number of reducers utilized for process the output of the Mapper is 1 which is configurable and can be changed by the user according to the requirement.


2 Answers

Redux assumes that you never mutate the objects it gives to you in the reducer. Every single time, you must return the new state object. Even if you don't use a library like Immutable, you need to completely avoid mutation.

case 'TOGGLE_CART':
    return !state.cartOpen;

Doing ^^ this is mutating your state (corrupting your state object). When you don't guarantee immutability, Redux loses its predictability and efficiency.

To achieve immutable state, we can use vanilla Object.assign or its more elegant alternative object spread syntax.

case 'TOGGLE_CART':
    return {
        ...state,
        cartOpen: !state.cartOpen
    }
like image 191
yadhu Avatar answered Oct 24 '22 15:10

yadhu


Your reducer must always return the complete slice of the app's state for which it is responsible. For TOGGLE_CART, you are only returning the boolean value for openCart.

Instead, create a copy of the previous state object and only update the single property you want to change:

case 'TOGGLE_CART':
    return Object.assign({}, state, {
        cartOpen: !state.cartOpen
    });
like image 21
TimoStaudinger Avatar answered Oct 24 '22 16:10

TimoStaudinger