Home > Back-end >  Only one few items gets saved to local storage
Only one few items gets saved to local storage

Time:07-11

I tried saving my cart items to local storage but only few of the item gets saved. If i add 2 items, 1 gets saved, if i add 3 items, 2 gets saved, if i add 4, 3 gets saved, and so on.

Here is my code to save them.

  const [state, dispatch] = useReducer(StoreReducer, {
    cart: 
       JSON.parse(localStorage.getItem("cart"))
      || [],
  });

  const addToCart = (product) => {
    dispatch({
      type: "ADD_TO_CART",
      payload: product,
    });
    localStorage.setItem("cart", JSON.stringify(state.cart));
  };

Here is an image describing what is looks like Here is a link to the image and describes what the application looks like and the local storage

CodePudding user response:

This function has a major flaw. React doesn't work synchronously.

const addToCart = (product) => {
  // this change will be made before next render
  dispatch({
    type: "ADD_TO_CART",
    payload: product,
  });
  // that's why this `state.cart` is not updated yet
  localStorage.setItem("cart", JSON.stringify(state.cart));
};

Try running

localStorage.setItem("cart", JSON.stringify(state.cart));

Inside the reducer

CodePudding user response:

I'd recommend using redux-persist

I'll give a simple example. Please tweak it according to your needs.

We basically have a localstorage.js file to save and read state from local storage.

File: localStorage.js

export const loadState = () => {
    try {
      const serialState = localStorage.getItem('cart');
      if (serialState === null) {
        return undefined;
      }
      return JSON.parse(serialState);
    } catch (err) {
      return undefined;
    }
};


export const saveState = (state) => {
    try {
      const serialState = JSON.stringify(state);
      localStorage.setItem('cart', serialState);
    } catch(err) {
        console.log(err);
    }
};

File: reducer.js

import {
  addToCart
} from './actions';

function reducer(state, action) {
  if (action.type === addToCart) {
    // example
    return { 
        ...state,
        cart: [...state.cart, action.payload]
    }
  }
  return state;
}

export default reducer;

We read data from localstorage.js by loadState method and put its value in the persistedState constant.

File: store.js

import reducer from './reducer';
import { createStore } from 'redux';
import { loadState } from './localStorage';
 
const persistedState = loadState();
 
const initialStore={
    /* state of your app */
    cart: [],
    persistedState
}
    
export const store=createStore(reducer, persistedState);

In our App.js, we subscribe state changes to store it to web browser's local storage.

File: App.js

import React from "react";
import { Provider } from 'react-redux';

import { store } from './store';
import { saveState } from './localStorage';
 
store.subscribe(() => {
  saveState({
    cart:store.getState().cart
  });
});

function App() {
  return (
    <Provider store={store}>
      <YourComponent />
    </Provider>
  );
}
 
export default App;

That's it. With this approach, there's no need to manually modify your local storage item.

  • Related