I have two different components that show different categories of food and trying to implement a save button for both of them using localStorage. I have this code on both of them
const [menu, setMenu] = useState([]);
const AddtoMenu = (e,selectedItem) => {
let newMenu;
if (menu.includes(selectedItem)) {
// If the item is already in the array, remove it
newMenu = menu.filter(item => item !== selectedItem);
} else {
// If the item is not in the array, add it
newMenu = [...menu, selectedItem];
}
setMenu(newMenu);
}
useEffect(() => {
localStorage.setItem('menu', JSON.stringify(menu));
}, [menu]);
What happens now is that they don't share the same storage, they replace each other depending on the last item I saved.. how can I make both of them add to the last added item?
CodePudding user response:
Put the state and state setter in a component that's an ancestor to both, and pass it down to both children.
const [menu, setMenu] = useState([]);
const addToMenu = (e,selectedItem) => {
// ...
};
useEffect(() => {
localStorage.setItem('menu', JSON.stringify(menu));
}, [menu]);
return (
<div>
<Child1 {...{ menu, addToMenu }} />
<Child2 {...{ menu, addToMenu }} />
</div>
);
const Child1 = ({ menu, addToMenu }) => {
// etc
If setMenu
is used in the children outside of addToMenu
, you can pass that down as well.
CodePudding user response:
To have both of your components add to the same localStorage, you can use a shared state that both components can access and update. One way to do this is to create a separate component that manages the state for the menu and use the useContext hook to provide the state to the other components.
Here's an example of how you can set this up:
- Create a context for the menu state:
const MenuContext = createContext();
- Create a component that manages the state for the menu and provides it to the other components:
const MenuProvider = (props) => { const [menu, setMenu] = useState([]);
useEffect(() => { localStorage.setItem('menu', JSON.stringify(menu)); }, [menu]);
return ( <MenuContext.Provider value={[menu, setMenu]}> {props.children} </MenuContext.Provider> ); }
Wrap your components in the MenuProvider component:
In each of your components, use the useContext hook to get the menu state and the setMenu function:
const [menu, setMenu] = useContext(MenuContext);
const AddtoMenu = (e, selectedItem) => { let newMenu; if (menu.includes(selectedItem)) { // If the item is already in the array, remove it newMenu = menu.filter(item => item !== selectedItem); } else { // If the item is not in the array, add it newMenu = [...menu, selectedItem]; } setMenu(newMenu); }
This way, both of your components will have access to the same menu state and can add items to it using the setMenu function. The state will also be persisted in localStorage, so when the page is refreshed, the menu will still contain the items that were added.