0

I'm building a react ecommerce website and I am using easy-peasy redux. I want to persist to localStorage when I add to cart. I can't find anything on their documentation about how to persist to localStorage. easy-peasy is configured to persist to sessionStorage; although there is a mention that it can be configured to localStorage.

I can currently add to cart but I can't set to localStorage.

Below is my store.js and product page

    import { createStore, action } from 'easy-peasy';

    const store = createStore({
    cartItems: JSON.parse(localStorage.getItem('cartItems')) ?? [],
    addToCart: action((state, payload) => {
    return {
    ...state,
    cartItems: [...state.cartItems, payload],
   };
   }),
   });

   export default store;

//Home (product page)

   import { collection, addDoc, getDocs } from 'firebase/firestore';
   import { db } from '../../firebase/config';
   import { products } from '../../figsofeden-products';
   import { Card, Row, Container, Col } from 'react-bootstrap';
   import { Link, useNavigate } from 'react-router-dom';
   import { useState, useEffect } from 'react';
   import { useStoreActions, useStore } from 'easy-peasy';

 const Home = () => {
 const [products, setProducts] = useState([]);
 const navigate = useNavigate();

 useEffect(() => {
 getData();
 }, []);

async function getData() {
try {
  const products = await getDocs(collection(db, 'products'));
  const productsArray = [];
  products.forEach((doc) => {
   
    const obj = {
      id: doc.id,
      ...doc.data(),
    };

    productsArray.push(obj);
  });

  setProducts(productsArray);
} catch (error) {
  console.log(error);
  }
 }

const addToCart = useStoreActions((actions) => actions.addToCart);

return (
<Layout>
  <Container fluid className="product-directory mx-auto">
    <Row xs={1} md={2} lg={3} className="g-2">
      {products.map((product, index) => {
        return (
          <Col key={product.id} className="g-2">
            <Card>
              <div className="product-wrapper position-relative">
                <div className="product-content">
                  <Card.Img
                    variant="top"
                    src={product.imageURL}
                    alt="img"
                  />
                  <Card.Body>
                    <Card.Text>{product.name}</Card.Text>
                    <Card.Text>NGN {product.price}</Card.Text>
                  </Card.Body>
                </div>
                <div className="product-actions">
                  <h3> NGN {product.price}</h3>
                  <div className="d-flex">
                    <button
                      className="mx-2"
                      disabled={product.quantity === 0 ? 'true' : ''}
                      onClick={() => addToCart(product)}
                    >
                      ADD TO CART
                    </button>
                    <button
                      onClick={() => {
                        navigate(`/productinfo/${product.id}`);
                      }}
                    >
                      VIEW
                    </button>
                  </div>
                  <div className="outofstock">
                    <p>
                      <em>{product.quantity > 0 ? '' : 'Out Of Stock'}</em>
                    </p>
                  </div>
                </div>
              </div>
            </Card>
          </Col>
        );
      })}
    </Row>
  </Container>
 </Layout>
  );
 };

export default Home;
mide358
  • 1
  • 2

2 Answers2

1
addToCart: action((state, payload) => {

// define cartItems with needed state values
const cartItems = [...state.cartItems, payload]

// after set it to local storage
window.localStorage.setItem("cartItems", JSON.stringfy(cartItems))

// and return the new state
return {
   ...state,
   cartItems
};
Dharman
  • 30,962
  • 25
  • 85
  • 135
0

Use easy-peasy persist helper

https://easy-peasy.vercel.app/docs/api/persist.html

// store.js

import { createStore, action } from 'easy-peasy';

const store = createStore(
    persist({
        cartItems: [],
        addToCart: action((state, payload) => {
            cartItems.push(payload)
        }),
    }, {
        storage: 'localstorage'
    })
);

export default store;

Note: You can mutate the state directly within an action to update your store - mutations are turned into immutable updates against your store via immer.

So use

cartItems.push(payload)

Rather than

return {
    ...state,
    cartItems: [...state.cartItems, payload],
}

Also I suggest storing your products in the store and retrieving them via a thunk

https://easy-peasy.vercel.app/docs/api/thunk.html