React Hook useState Не обновляет интерфейс - PullRequest
2 голосов
/ 11 января 2020

Я новичок в React Hooks и пытаюсь обновить количество в корзине, используя следующий код:

import React, { useState, useEffect } from "react";
import cookie from "react-cookies";
import CheckoutItems from "./CheckoutItems";
import restHelper from "../../shared/RestHelper";

const Checkout = () => {
    const [cart, setCart] = useState(null);

    useEffect(() => {
        const cartId = cookie.load("RbCartId");

        if (cartId){
            (async () => {
                const cart = await restHelper.getUserCart(cartId);
                setCart(cart);
            })();
            }
    }, []);

    const handleQtyUpdate = (evt, id) => {
        let _cart = cart;
        let items = _cart.cartItems.filter(x => x.id === id);
        let cartItem = { ...items[0] };
        cartItem.quantity = Number(evt.target.value);
        const index = _cart.cartItems.findIndex(x => x.id === cartItem.id);
        _cart.cartItems[index] = cartItem;
        setCart(_cart);
    };

    return (
        <section>
            <div className="container" style={{ marginTop: "80px" }}>
                <h3 className="rb-highlight">Shopping Cart</h3>
                <table className="table" style={{marginTop: "20px"}}>
                    <thead>
                        <tr>
                            <th>Items</th>
                            <th style={{ textAlign: "right" }}>Price</th>
                            <th style={{ textAlign: "right" }}>Quantity</th>
                            <th style={{ textAlign: "right" }}>Total</th>
                        </tr>
                    </thead>
                    <tbody>
                        <CheckoutItems cart={cart} onQtyUpdate={handleQtyUpdate} />
                    </tbody>
                </table>
            </div>
        </section>
    );
}
export default Checkout;

Компонент CheckoutItems:

import React from "react";

function CheckoutItems({cart, onQtyUpdate}){
    if (!cart || cart.cartItems === 0){
        return <tr><td colSpan="4"><span className="rb-highlight">There are no items in your cart</span></td></tr>;
    }
    else{
        const cartItems = cart.cartItems.map((item, index) => {
            return <tr key={index}>
                <td>{item.description}</td>
                <td style={{textAlign: "right"}}>&euro;{item.cost}</td>
                <td style={{textAlign: "right"}}><input type="text" id={item.id} name="quantity" value={item.quantity} onChange={(evt) => onQtyUpdate(evt, item.id)} /></td>
                <td style={{textAlign: "right"}}>&euro;{item.cost * item.quantity}</td>
            </tr>
        })
        return cartItems;
    }
}

export default CheckoutItems;

элементы корзины успешно обновлены в handleQtyUpdate, но значение в пользовательском интерфейсе не обновляется. Из того, что я прочитал, я должен использовать useEffect для обновления корзины, но я не уверен, как go использовать ее с handleQtyUpdate.

Ответы [ 2 ]

6 голосов
/ 11 января 2020

Проблема в том, что сравнения состояний невелики, то есть, в случае объекта будет сравниваться только ссылка.

В вашем примере вы обновляете свойство cartItems, но не экземпляр объекта, поэтому Что касается React, то состояние не изменилось, поскольку он не будет проверять отдельные свойства.

Попробуйте каждый раз создавать совершенно новую корзину, и вы должны увидеть обновление пользовательского интерфейса, например,

 setCart({ ..._cart })
0 голосов
/ 11 января 2020

У вас должна быть копия объекта с использованием оператора распространения

setCart ({..._ cart})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...