简体   繁体   中英

Update ReactJS state array

I have a ReactJS component that renders a list of orders. I get orders from a REST API. The format of the data is the following:

{
    "count": 2,
    "orders": [
        {
            "order_number": 55981,
            "customer_number": 24742
        },
        {
            "order_number": 55980,
            "customer_number": 24055
        }
    ]
}

Each order can have a list of items. When I click on an order, I get the list of items in the following format:

{
    "count": 2,
    "items": [
        {
            "name": "Green pillow",
            "status": "pending"
        },
        {
            "name": "Red pillow",
            "status": "delivered"
        }
    ]
}

The orders list is refreshed automatically and can change any time, so I store the orders list in this.state which gets updated via ajax. this.state looks like this:

{
    "orders": [
        {
            "order_number": 55981,
            "customer_number": 24742
        },
        {
            "order_number": 55980,
            "customer_number": 24055
        }
    ]
}

My problem is that I would like that, when I click on an order, the state gets updated so that the clicked order contains the items associated to that order. The order list would look like this after clicking on an item:

{
    "count": 2,
    "orders": [
        {
            "order_number": 55981,
            "customer_number": 24742,
            "items": [
                {
                    "name": "Green pillow",
                    "status": "pending"
                }
            ]
        },
        {
            "order_number": 55980,
            "customer_number": 24055
        }
    ]
}

How can I add items to a specific order using this.setState()? The problem is that setState seem to update data using keys, but my orders are in an array. I can probably copy the whole array and put the items key inside, but that seems overkill. Am I taking the wrong approach?

I'm not entirely sure I got your question, but I think that what you're trying to achieve is add new orders to an array (push) which is located in your state.

If that's the case, you should something like this:

// since you're orders it's not a plain array, you will have
// to deep clone it (e.g. with lodash)

let orders = _.clone(this.state.orders);
orders.push(newOrder);
this.setState(orders);

Why cloning the state before changing it is important?

Immutability comes with some great properties (like easy equality comparison) and the React team is aiming towards that direction to improve performance more and more.

As of React 0.13 mutating state without calling this.setState will trigger a warning, and it will break entirely at some point in React's future (see the docs )

Hope this helps

Make a copy of the current state, modify the copy and use it as the new state.

This is just a simple example. You might want to add some caching logic so you don't have to retrieve the order's item again and again when a user click on the same order multiple times.

var updatedOrder = _.clone(this.state.orders);

updatedOrder[0]["items"] = [ { "name": "Foo", "status":"bar" } ];

this.setState({
  orders: updatedOrder
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM