So I am building an e-commerce website checkout page with commerce.js. I have a context that allows me to use the cart globally. But on the checkout page when I generate the token inside useEffect , the cart variables have not been set until then.
My context is as below
import { createContext, useEffect, useContext, useReducer } from 'react';
import { commerce } from '../../lib/commerce';
//Provides a context for Cart to be used in every page
const CartStateContext = createContext();
const CartDispatchContext = createContext();
const SET_CART = 'SET_CART';
const initialState = {
id: '',
total_items: 0,
total_unique_items: 0,
subtotal: [],
line_items: [{}],
};
const reducer = (state, action) => {
switch (action.type) {
case SET_CART:
return { ...state, ...action.payload };
default:
throw new Error(`Unknown action: ${action.type}`);
}
};
export const CartProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, initialState);
const setCart = (payload) => dispatch({ type: SET_CART, payload });
useEffect(() => {
getCart();
}, []);
const getCart = async () => {
try {
const cart = await commerce.cart.retrieve();
setCart(cart);
} catch (error) {
console.log('error');
}
};
return (
<CartDispatchContext.Provider value={{ setCart }}>
<CartStateContext.Provider value={state}>
{children}
</CartStateContext.Provider>
</CartDispatchContext.Provider>
);
};
export const useCartState = () => useContext(CartStateContext);
export const useCartDispatch = () => useContext(CartDispatchContext);
Now on my checkout page
const CheckoutPage = () => {
const [open, setOpen] = useState(false);
const [selectedDeliveryMethod, setSelectedDeliveryMethod] = useState(
deliveryMethods[0]
);
const [checkoutToken, setCheckoutToken] = useState(null);
const { line_items, id } = useCartState();
useEffect(() => {
const generateToken = async () => {
try {
const token = await commerce.checkout.generateToken(id, {
type: 'cart',
});
setCheckoutToken(token);
} catch (error) {}
};
console.log(checkoutToken);
console.log(id);
generateToken();
}, []);
return <div> {id} </div>; //keeping it simple just to explain the issue
};
In the above code id is being rendered on the page, but the token is not generated since on page load the id is still blank. console.log(id) gives me blank but {id} gives the actual value of id