Search code examples
javascriptreactjsreduxreact-reduxredux-toolkit

Trying to toggle a Redux boolean on a button click, however the toggle only works the first time and I'm not sure why


I have a very simple redux slice that has 2 reducers which toggle a boolean to either on or off and a function inside of a hook that dispatches these actions depending on the current forceToggle state. By default forceToggle is false, so the first click should change forceToggle to true.

When I click the button for the first time, forceToggleOn gets dispatched which changes forceToggle to true which is what I expect.

The problem is that if I click that button again, I expect that forceToggleOff would get dispatched because forceToggle is true and change forceToggle to false, but this does not happen anymore. Only the first toggle works.

import { createSlice } from '@reduxjs/toolkit';

export type ToggleState = {
    forceToggle: boolean;
};

const initialState: ToggleState = {
    forceToggle: false,
};

export const toggleSlice = createSlice({
    name: 'activity',
    initialState,
    reducers: {
        forceToggleOn: (state) => {
            state.forceToggle = true;
        },
        forceToggleOff: (state) => {
            state.forceToggle = false;
        },
    },
});

export const { actions: toggleActions, reducer: toggleReducer } = toggleSlice;

The function that gets called on button click:

const test = () => {
    forceToggle ? dispatch(forceToggleOff()) : dispatch(forceToggleOn());
};

Solution

  • Try

    const toggleForceNativeActivities = useCallback(() => {
        forceNativeActivities ? dispatch(toggleForceNativeActivitiesOff()) : dispatch(toggleForceNativeActivitiesOn());
        setItem(PERSISTED_FORCED_ACTIVITY_KEY, forceNativeActivities.toString());
    }, [forceNativeActivities]);
    

    Your handler is working with a stale value without useCallback.