0

I am still new to React js.

I am trying to use useState({}) to define an object of objects of orders. For the newOrderHandler, I am passing the order to be added.

The idea is to add a new object if the order title does not exist and update the amount if the order title already exists in the orders state.

This is the code:


  const [orders, setOrders] = useState({});

  const newOrderHandler = (newOrder) => {

    setOrders(prevOrders => {
      console.log('prevOrderss', prevOrders)
      // console.log(`prevOrders[newOrder.title]`, prevOrders[newOrder.title])
      let newOrders = prevOrders;
      if (newOrders[newOrder.title] == null) {
        newOrders[newOrder.title] = newOrder
      } else {
        newOrders[newOrder.title].amount = +prevOrders[newOrder.title].amount + +newOrder.amount
      }
      return newOrders;
    });
  };

The problem here is that although when I log the prevOrders to the console, I get it as I wanted:

enter image description here

However, when I calculate the number of objects in the Navigation component, it just displays 0 always.

This is the code that calculates the number of objects in the Navigation component:

Your Cart <span>{Object.keys(props.orders).length}</span>

This is how I passed the props to the Navigation component:

<Navigation orders={orders} />

This always displays 0. I guess the problem is when defining this: let newOrders in the setOrders function, but I am not sure how to solve it.

Thanks in advance.

1
  • 2
    let newOrders = prevOrders; does not copy/clone/crete a new object. I suggest you should read reference types and working with immutable objects Commented Jul 20, 2021 at 9:09

1 Answer 1

1

The problem is that you React cannot detect that you have changed the object. You need to make a copy, you are passing in the same reference.

newOrders == prevOrders returns true.

What is standard is to make a copy so that you do not mutate the state and react can detect that the object has actually changed.

You can use the spread operator.

 let newOrders = { ...prevOrders, [newOrder.title] : { ...prevOrders[newOrder.title] }};

  if (newOrders[newOrder.title] == null) {
        newOrders[newOrder.title] = newOrder
  } else {
        newOrders[newOrder.title].amount = +prevOrders[newOrder.title].amount + +newOrder.amount
      }
      return newOrders;

Spreading the nested property too because you are mutating its amount property. For every level of nesting you will have to use spread for the property you want to change.

Sign up to request clarification or add additional context in comments.

1 Comment

Glad. Please check edit, and read up on cloning nested objects.

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.