Reputation: 13
I stored an object in the reducer, I retrieve using useSelector <definitely :) > it and I use as the initial value for useState as bellow
const Product = useSelector(state => state.reducer.selectedMeal);
const [SelectedMeals, setSelectedMeals] = useState({...Product});
and I have this function to change the quantity which is one of the attributes
const Increase = () => {
let copy = {...SelectedMeals};
copy.featuresList.items.qty += 1
setSelectedMeals(copy);
}
ISSUE: the value in Product.featuresList.items.qty //changed as well
Upvotes: 1
Views: 325
Reputation: 42160
You are mutating state by doing this because the featuresList
inside of copy
is the same as the one in the SelectedMeals
state and the one is the Product
in the reducer. You are dealing with a shallow copy.
Your Product
variable will subscribe to the latest changes in your redux store.
You only need local component state for data that you don't want to push to the redux state, such as form inputs or other UI data.
I would advise that your useState
hooks (you can have multiple) should store the minimum amount of data that you need to describe the local changes. You probably don't need to copy the whole Product
.
Here's an example where the only local state is a number
of the current quantity.
const [qty, setQty] = useState(Product.featuresList.item.qty);
const increase = () => {
setQty( prev => prev + 1 );
}
Updating a state property that's three-levels deep without mutation is really annoying, but you can do it:
const increase = () => {
setSelectedMeals((product) => ({
...product,
featuresList: {
...product.featuresList,
items: {
...product.featuresList.items,
qty: product.featuresList.items.qty + 1
}
}
}));
};
Upvotes: 1