我正在嘗試使用反應背景關系創建購物車機制。
這是我的背景關系提供者
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 是使用父組件背景關系的子視圖
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>
);
}
子視圖應該能夠正確更新背景關系。問題是父 App 在更新背景關系后沒有重新渲染 MenuItemDetailsView 組件。(App 組件重新渲染自身
這是我的代碼的沙箱
https://codesandbox.io/s/react-context-demo-cart-eyjx2
我不太明白這里的問題。App 組件不應該也重新渲染它的子組件嗎?如果沒有,我怎么能告訴他在更新背景關系時重新渲染?
我理解在更新數量時設定本地子變數并更新變數和背景關系本身的可能性,但我覺得這將是解決實際問題的方法。
SN:當退出 MenuItemView 并重新進入它(從多頁應用程式,未顯示在沙箱中)時,數量會更新,這意味著 useContext 正常作業并且每次重新呈現 MenuItemView 時都會正確讀取購物車專案。但我再次希望購物車在不離開組件并手動回傳的情況下得到更新
uj5u.com熱心網友回復:
這里的問題是您正在改變購物車狀態。
let newCart = cart;
ThenewCart仍然參考您保持在 state 中的同一個物件,因此當您 update 時newCart,您也在發生變異cart。一旦你這樣做了setCart(newCart),React 就會退出狀態更新(和重新渲染),因為它和以前是同一個物件。在React 檔案中有更多關于 React 在更新狀態時如何比較物件的資訊。
這里的解決方案是首先將狀態復制為新物件:
const newCart = { ...cart };
或者更好的是,使用功能狀態更新:
setCart(prevCart => {
const newCart = { ...prevCart };
// do stuff with newCart
return newCart;
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/399855.html
