Naif Ahmed
Naif Ahmed

Reputation: 13

useState change values in reducer REACT JS

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

Answers (1)

Linda Paiste
Linda Paiste

Reputation: 42160

State Mutation

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.


Minimize Component State

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 );
}

Nested Updates

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

Related Questions