更改数组中的对象不会触发 html React 中的更改

Changing object in an array does not trigger change in html React

我要编辑的对象以 JSON 格式编辑,但只有以前的数据显示在浏览器中。我使用这些挂钩从本地存储中获取产品列表

const Cart = () => {
    const [products, setProducts] = useState([]);
    const [loading, setLoading] = useState(true);

    useEffect(()=>{
        setProducts(loadCart());
        setLoading(false)
    },[])

然后我映射所有对象

   const mapProducts = (products) => {
        return (
            <>
                {products.map((product) => {
                    return (
                        <>
                            <div className="cart-detail">
                                <h4>{product.name} - {product.price}$ 
                                / total: {product.price * product.amount}$</h4>

                                <h4>{product.amount}</h4>
                                <button onClick={() => incrementAmount(product)}>+</button>
                            </div>
                            
                        </>
                    )
                })}
            </>
        )
    }

    return (
        <Base title="Cart">
            {loading && <h1>Loading...</h1>}
            {!loading && mapProducts(products)}
        </Base>
    )

incrementAmount() 函数看起来像这样:

    const incrementAmount = (product) => {
        let tempList = products
        for (let i = 0; i < tempList.length; i++) {
            if (tempList[i].id === product.id) {
                tempList[i].amount++;
            }
        }
        setProducts(tempList)
    }

从我在控制台中看到的情况来看,数组看起来很好,我想要编辑的对象已被编辑。 FE:我有一个对象 {name:"hoodie", amount:3} 在点击 "+" 按钮后它正确地更改为 {name:"hoodie", amount:4}(在两个 productstempList) 但仅在控制台中,在文档中它仍然显示 product.amount 为 3 我不知道为什么

您可以传递一个函数,而不是将对象传递给 setState,当您有一个对象进入您想要保留旧值的状态时,您必须使用一个函数。

因为state可能会异步更新,所以你不应该依赖它们的值来计算下一个状态。

您必须像这样更改 incrementAmount() 函数:

const incrementAmount = (product) => {
    setProducts(prevState => {
        const newState = [...prevState];
        for (let i = 0; i < newState.length; i++) {
          if (newState[i].id === product.id) {
            newState[i].amount++;
          }
        }
        return newState;
     });
}

这是因为只有当状态发生变化时,react 才会触发重新渲染。当您在 incrementAmount 中调用 setProducts 时,您实际上是在传递相同的对象(更新了一个嵌套的 属性)。所以 React 不会将此注册为状态更改。这是由于对象和数组在 Javascript 中的工作方式。 为了让您的代码正常工作,请将 let tempList = products 更改为 let tempList = [...products]。这将在内存中创建一个新对象并从 products 复制值。最后,当您将其传递给 setProducts 时,将触发重新渲染以更新您的 HTML.