Cart
组件中 insertToCart()
函数中的 .push()
推送了两次,不知道为什么。由于所有日志都运行一次,我认为它应该可以工作,appendToCart()
工作完美。我有意返回函数的先前值,以免触发整个应用程序的重新渲染。任何帮助将不胜感激。
编辑: saveItem()
被调用两次。
export default function Cart({ children }) {
const [cart, setCart] = useState([]);
useEffect(() => {
setCart(JSON.parse(localStorage.getItem('frentesRosarinos')) || []);
}, []);
function insertToCart(product, amount) {
console.log('insert');
setCart((pc) => {
pc.push({ ...product, amount });
localStorage.setItem('frentesRosarinos', JSON.stringify(pc));
return pc;
});
}
function appendToCart(id, amount) {
console.log('append');
setCart((pc) => {
const savedItem = pc.find((c) => c.id === id);
savedItem.amount = amount;
localStorage.setItem('frentesRosarinos', JSON.stringify(pc));
return pc;
});
}
return (
<CartContext.Provider
value={{ cart, insertToCart, appendToCart }}
>
{children}
</CartContext.Provider>
);
}
export default function Product({ product, isCart }) {
const { cart, appendToCart, insertToCart } =
useContext(CartContext);
const [addItemClosed, setAddItemClosed] = useState(true);
const [amount, setAmount] = useState(
product.amount || cart.find(({ id }) => id === product.id)?.amount || 0,
);
const amountToAdd = useRef(0);
function saveItem(value) {
setAmount((pa) => {
const newAmount = parseInt(value) + pa;
pa === 0 ? insertToCart(product, newAmount) : appendToCart(product.id, newAmount);
return newAmount;
});
amountToAdd.current.value = 0;
}
return (
<div className={styles.container}>
<div className={styles.addItemsContainer}>
<p
onClick={() => setAddItemClosed((ps) => !ps)}
className={`${styles.addItemsButton} ${addItemClosed ? styles.addBorders : ''}`}
>
Agregar más items
</p>
<div
className={`${styles.quantity} ${
addItemClosed ? styles.addBorders : styles.firstChildHide
}`}
>
<span>Ingrese una cantidad</span>
<input ref={amountToAdd} type='number' />
</div>
<p
className={`${styles.addOne} ${
addItemClosed ? styles.addBorders : styles.secondChildHide
}`}
onClick={() => saveItem(amountToAdd.current.value)}
>
Agregar
</p>
</div>
<div style={{ margin: '10px 0' }}>
<PressButton action={() => saveItem(1)} size='medium' lightMode>
{isCart ? 'Agregar otro' : 'Añadir al carrito'}
</PressButton>
</div>
</div>
);
}
最佳答案
I'm returning the previous value on the functions on purpose, to not trigger a re-render of the whole app. Any help would be much appreciated
你不应该这样做,官方 React 文档说你应该以不可变的方式更新状态,并且你应该遵循这个建议。 也在这里:
pc.push({ ...product, amount });
你再次进行突变,这是不对的。
PS。另外,一般来说,在功能设置状态内调用函数时应小心,以防它们产生副作用,因为在严格模式下,将调用 setter 函数 twice 。在另一个设置状态中调用一个设置状态(如在setAmount
中调用 setCart
)可能会被视为副作用。
关于javascript - .push() 在 Next.js 上不正确地推送两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72254949/