Home > Software engineering >  How to keep state from refreshing while changing routes in React
How to keep state from refreshing while changing routes in React

Time:08-16

I'm building a simple wine store themed e-commerce app and I would like to keep the amount of products in the cart visible in the header at all times. It's initially set at 0. My app is constructed in a way that every product has its own page (route) and when I click on "Add To Cart", the amount of cart item in the header updates ( 1 for every click). However, when I go back to choose other products, the amount of cart items in the header refreshes back to 0 and the whole cart is empty again.

I'm keeping my cart in a state:

const [cart, setCart] = useState([]);

This is the function that is called every time the "Add to Cart" button is clicked:

const handleAddToCart = (id, newAmount) => {
if(cart.find(cartItem => cartItem.id === id)){
  setCart(cart => cart.map(cartItem => {
    if(cartItem.id === id) return {...cartItem, amount: cartItem.amount   newAmount}
    return cartItem
  }));
  return;
}
setCart([...cart, {...getProductById(id), amount: newAmount}])}

This is how I get my cart size (also the function that I send as a prop to the Header component):

const reducer = (acc, current) => acc   current;


const getCartSize = () => (
    cart.map(cartItem => cartItem.amount).reduce(reducer, 0)
  );

These are my routes:

<BrowserRouter>
  <Header getCartSize={getCartSize}/>
  <Routes>
    <Route path="/home" element={<Home />} />
    <Route path="/products" element={<Products wines={products}/>} />
    <Route path="/contact" element={<Contact />} />
    <Route path="/cart" element={<Cart cart={cart} getCartTotal={getCartTotal} getCartSize={getCartSize} handleCartDelete={handleCartDelete} handleCartUpdate={handleCartUpdate}/>} />
    {wines.map((wine) => (
      <Route key={wine.id} path={`/products/${wine.url}`} element={<Item item={wine} handleAddToCart={handleAddToCart} />}/>
    ))}
  </Routes>
  <Footer />
</BrowserRouter>

How do I keep the cart from emptying on every route change?

CodePudding user response:

You can use context for that state is not lost every time the route changes. BUT when page is refreshed, state loses again too, can use localstorage for this prevent.

const CartContext = createContext({cart:[],setCart : () => {}})

const CartProvider = (children) => {
  const [cart,setCart] = useState([])
  
  return <CartContext.Provider value={{ cart, setCart }}> 
            {children} 
         </CartContext.Provider>
}

usage: wrap routes with CartProvider.

<CartProvider>
  ...Routes
</CartProvider>

and can fetch and set with useContext.

const {setCart,cart} = useContext(CartContext)

can use cookie or localStorage for state keep when page refresh.

const CartProvider = (children) => {
  const [cart,setCart] = useState(localStorage.getItem("key") || [])
  const handleChange = (cart) => {
     setCart(cart)// can do another calculation
     localStorage.setItem("key",state);
  }
  return <CartContext.Provider value={{ cart, handleChange }}> 
            {children} 
         </CartContext.Provider>
}

CodePudding user response:

I solved it myself - I simply used react-router-dom instead of tags for navigating.

  • Related