Search code examples
reactjsredux

Redux : dispatch not changing state


I have some buttons, i want to change button backgroundColor when clicked. I tested color redux state on the console. Dispatch not changing redux state. here is the code and console;

import { useDispatch } from "react-redux"
import { initColor } from "./color"

export default function Question(props) {

const dispatch = useDispatch()
const color = useSelector((state) => state.color.value)

function toggleBtnBgColor(btn, correctAnswer) {
    if(flag) {
        console.log(color)
        if(color == "light-bg-color") {
            dispatch(initColor("dark-bg-color"))
            console.log(color)
            btn.target.classList.add(color)
        }

On the console output;

light-bg-color
light-bg-color

createSlice file;

import {createSlice} from "@reduxjs/toolkit"
export const colorSlice = createSlice({
name: "color",
initialState: {value: "light-bg-color"}, 
reducers: {
    initColor: (state,action) => {
        state.value = action.payload
    }
}
})
export const {initColor} = colorSlice.actions
export default colorSlice.reducer

Solution

  • After dispatch, color is still set to the old color value (it does not get updated after dispatch). The color here is "stale" until the component gets re-rendered (Question function is run again). In that moment, useSelector will return the new upated color. BTW: you should determine set the list of classnames depending on the outcome of the useSelector call and then set the names when you render your button (declaratively).

    Simplified:

    import { useDispatch } from "react-redux"
    import { initColor } from "./color"
    
    export default function Question(props) {
    
    const dispatch = useDispatch()
    const color = useSelector((state) => state.color.value)
    const btnClassNames = color === "light-bg-color" ? "classname-for-light" : "classname-for-dark"
    
    function toggleBtnBgColor(btn, correctAnswer) {
        if(flag) {
            console.log(color)
            if(color == "light-bg-color") {
                dispatch(initColor("dark-bg-color"))
            }
        }
    }
    return <button className={btnClassNames} onClick={...}>...</button>