Tarik
Tarik

Reputation: 60

How to change an object in React-redux state using a Hook

I haven't touched react in a while and it shows, not that I was very good to begin with. I'd like a Hook to change a value of an object in state. It would "toggle" an active: bool key-pair value in the object.

object inside initial state:

    hexInfo: {
        name: "Hex Squadron",
        active: true,
    // more stuff in object
    }

Hook:

    import React from 'react';
    import SquadronIcon from './SquadronIcon';
    import { useDispatch } from 'react-redux';


    let SquadronsMenu = () => {
        const dispatch = useDispatch();

        // HEX
        let seeHexInfo = () => dispatch({
            type: "INFO_HEX"
        });

    return(
            <>
            {/* Hex */}
            <SquadronIcon handleClick={ seeHexInfo } image={ importedImage } alt="" text="" />
        )
    }

    export default SquadronsMenu;

reducer so far:

    let reducer = (state, action) => {
        switch (action.type) {

            // INFO
            case "INFO_HEX": return { ...state, hexInfo: { active: !active }} 
        
            default: return state;
        }
    };
  1. when I just put a active: false it naturally overwrites the entire object
  2. As it is now (with !active) I get an error 'activ' is not defined no-undef

Upvotes: 0

Views: 1381

Answers (1)

bryyytl
bryyytl

Reputation: 491

There are two different ways that I can easily think to accomplish this.

Option 1: Utilize the spread operator. This option requires you to not only spread the reducer state but also everything within state.hexInfo.

const reducer = (state, action) => {
    switch (action.type) {

       // INFO
       case "INFO_HEX":
           return { 
               ...state,
               hexInfo: {
                   ...state.hexInfo, 
                   active: !state.hexInfo.active, 
               }
           } 
        
       default: return state;
   }
};

Option 2: If you are willing to use an additional library, check out immer (https://immerjs.github.io/immer/docs/example-reducer). It is great for simplifying reducers so that you do not have to use the spread operator directly. Here is a link to the most common update patterns with immer https://immerjs.github.io/immer/docs/update-patterns.

import produce from 'immer';

const initialState = {
    hexInfo: {
        name: "Hex Squadron",
        active: true,
    }
};

const reducer = (state = initialState, action) =>
    produce(state, (draft) => {
        switch (action.type) {
            case INFO_HEX:
                draft.hexInfo.active = !state.hexInfo.active;
                break;
            default:
        }
    });

export default reducer;

Upvotes: 3

Related Questions