0

I am facing a very unique problem with my app. I have created a redux store in my next app. It's a pizza app. Customer clicks on add to cart button which adds it to the redux store.

The problem that I face is that on the first click, it's not working as expected. On the second click on the same item, it adds to the state. On subsequent click for the same item, it is working as normal.

However, for different pizza items, it is facing the same problem. The first click is not adding to the state. Second clicks add to the state and subsequent clicks are working as normal.

I am facing a problem with my first clicks only.

Here is my add to cart component: -

function AddToCartButton({ id, size }) {

    const [text, setText] = useState("Add");
    const dispatch = useDispatch();
    const state = useSelector(state => state.cart);

    const clickHandler = event => {
        event.preventDefault();
        buttonTextHandler();

        //Dispatch to redux
        dispatch(addPizza(id));
        console.log("Test state: ", state); //First clicks are always empty
    }

    //Changes text when item is added to the cart
    const buttonTextHandler = () => {
    .....
    }

    return (
        <div>
            <button
                className={`addToCartButton${size ? `-${size}` : ''}`}
                onClick={clickHandler}
            >{text}</button>
        </div>
    )
}

My reducer: -

import { HYDRATE } from "next-redux-wrapper";

export const cartReducer = (state = [], action) => {
    switch (action.type) {
        //Required by next-js-reducer library
        case HYDRATE:
            return { ...state, ...action.id };

        //Add pizza to cart, if exists increment the pizza
        case 'ADD_PIZZA':
            //If pizza is already in the cart
            const findPizzaIfAdded = state.find(pizza => pizza.id === action.id);
            if (findPizzaIfAdded !== undefined) {
                const modifiedQuantity = {
                    ...findPizzaIfAdded,
                    quantity: findPizzaIfAdded.quantity + 1
                }
                return state.map(pizza => pizza.id === action.id ? modifiedQuantity : pizza);
            }

            const newPizza = {
                id: action.id,
                quantity: 1
            }

            return [
                ...state,
                newPizza
            ]

        default:
            return state
    }
}

export const addPizza = id => {
    return {
        type: 'ADD_PIZZA',
        id
    }
}

Here is my store.js

import { applyMiddleware, combineReducers, createStore } from "redux";
import { cartReducer } from "./reducers/cartReducer";
import { createWrapper } from 'next-redux-wrapper';
import thunk from "redux-thunk";

const rootReducer = combineReducers({
    cart : cartReducer
})

const makeStore = context => createStore(rootReducer);
export const wrapper = createWrapper(makeStore, applyMiddleware(thunk));
killerprince182
  • 455
  • 2
  • 12
  • 1
    If you're relying on `console.log(...)` to know the `state`, the `state` update won't reflect as soon as you hit `dispatch`. Only in the next render you will get the latest state when `useSelector` is called again. You can accurately know the button click effect via a `useEffect` which triggers only when `state` changes and keep your `console.log(...)` inside it. – Lakshya Thakur Jan 15 '22 at 18:27
  • Thanks, that solved my problem. – killerprince182 Jan 15 '22 at 18:39
  • Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – juliomalves Jan 16 '22 at 11:03

0 Answers0