0

I have setup a useState hook as follows.

  const [products, setProducts] = useState([
    {
      id: 1,
      qty: 0,
    },
    {
      id: 2,
      qty: 0,
    }
  ]);

I have a TouchOpacity component which fires the following function when pressed.

 const _onPress = () => {
    const productArr = products;
    productArr[0].qty = value;
    setProducts(productArr);
  };

The expected outcome is that product with id 1 must increase the qty to 1, however this does not happen.

When i use the spread operator for the products from state as follows it works as expected.

 const _onPress = () => {
    const productArr = [...products];
    productArr[0].qty = value;
    setProducts(productArr);
  };

What is the reason for this ?

4
  • 1
    With your first code block you attempt to mutate state directly (which is not recommended to do and won't trigger re-render). Second block does shallow copy of state array and properly assigns modified version of that array to products Commented Mar 6, 2020 at 11:55
  • Why is const productArr = products; not considered as copying an array ? I am creating a new variable right ? Commented Mar 6, 2020 at 12:00
  • @Muljayan it's called copying the reference. Commented Mar 6, 2020 at 12:02
  • Got it. Thanks alot. Commented Mar 6, 2020 at 12:04

1 Answer 1

1

Note that even with the spread operator, in both of your examples, you are mutating the state.

If you need to use arrays inside your state or nested structures, I would highly recommend trying a library such as immer which will simplify things, is more efficient than recreating objects, and overall will give you a very good sense of notion of not mutating the state:

import produce from "immer";

const [products, setProducts] = useState([
  {
    id: 1,
    qty: 0,
  },
  {
    id: 2,
    qty: 0,
  }
]);

const _onPress = () => {
  setProducts(
    produce(products, draft => draft[0].qty = value)
  );
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.