Child 更新上下文 React 后组件未更新

Child Components not being updated after updating context React

我正在尝试使用 React 上下文创建购物车机制。

这是我的上下文提供程序

export default function App() {
  const [cart, setCart] = useState(cartInitialState);

  return (
    <CartContext.Provider value={{ cart, setCart }}>
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
      </div>
      <MenuItemDetailsView />
    </CartContext.Provider>
  );
}

购物车初始状态是一些虚拟的空购物车。 MenuItemDetailsView 是一个 child 视图,它使用 parent 组件上下文

function MenuItemDetailsView() {
  const { cart, setCart } = useContext(CartContext);

  const findItemInCart = () => {
      //return quantity of cart item with specific id
  };

  const handleAdd = () => {
    const itemIndex = cart.items.findIndex((item) => item.id === 0);

    let newCart = cart;
    console.debug(newCart);
    if (itemIndex === -1) {
      //do stuff
    } else {
      //do stuff
    }
    setCart(newCart);
  };

  return (
    <div>
      <h1>{findItemInCart()}</h1>
      <button onClick={handleAdd}>add</button>
    </div>
  );
}

child 视图应该能够正确地更新上下文。问题是 parent 应用程序在更新上下文后没有重新呈现 MenuItemDetailsView 组件。 (App 组件重新渲染自身

这是我的代码的沙箱

https://codesandbox.io/s/react-context-demo-cart-eyjx2

我不太明白这里的问题。 App 组件不应该重新渲染它的 children 吗?如果不是,我怎么告诉他在更新上下文时重新渲染?

我理解设置本地 child 变量并在更新数量时同时更新变量和上下文本身的可能性,但我认为这将是解决实际问题的方法。

SN:退出 MenuItemView 并重新进入时(从多页应用程序,未显示在沙盒中)数量得到更新,这意味着 useContext 正常工作并且每次 MenuItemView 时都正确读取购物车项目正在重新渲染。但是我再次希望购物车得到更新而无需退出组件并手动返回

这里的问题是您正在改变购物车状态。

let newCart = cart;

newCart 仍然引用您保持状态的同一个对象,因此当您更新 newCart 时,您也在改变 cart。一旦你做了 setCart(newCart),React 就会退出状态更新(和重新渲染),因为它和以前是同一个对象。 React docs.

中有更多关于 React 在更新状态时如何比较对象的信息

这里的解决方法是先复制状态作为一个新的对象:

const newCart = { ...cart };

或者更好的是,使用功能状态更新:

setCart(prevCart => {
  const newCart = { ...prevCart };
  // do stuff with newCart
  return newCart;
});