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.