I'm working on a tutorial and i'm having an issue after adding react spring transition on the checkout page handled by Checkout.js component.
My problem happens when removing items from the basket, the last item on the basket never remove from the DOM even when the array removed the element via reducer.
This was working as expected before adding a transition and animated.div element to checkout component below.
import React from "react";
import "./Checkout.css";
import SubTotal from "./SubTotal";
import { useStateValue } from "../StateProvider";
import CheckoutProduct from "./CheckoutProduct";
import shortid from "shortid";
import { useTransition, animated } from "react-spring";
function Checkout() {
const [{ basket, user }] = useStateValue();
const getRandomKey = () => {
return shortid.generate();
};
// define transition behaviour
const transition = useTransition(basket, basket => basket.id, {
from: { opacity: 0, marginLeft: -100, marginRight: 100 },
enter: { opacity: 1, marginLeft: 0, marginRight: 0 }
});
return (
<div className="checkout">
<div className="checkout__left">
<img
className="checkout__ad"
src="https://images-na.ssl-images-amazon.com/images/G/02/UK_CCMP/TM/OCC_Amazon1._CB423492668.jpg"
alt=""
></img>
<div className="checkout__title">
<h3>Hello, {user?.email}</h3>
<h2>Your shopping basket</h2>
{transition.map(({ item, key, props }) => {
const keyNew = getRandomKey();
console.log(keyNew + "this is the new key");
return (
<animated.div
key={keyNew}
style={props}
className="checkout__product"
>
<CheckoutProduct
id={item.id}
image={item.image}
price={item.price}
rating={item.rating}
title={item.title}
/>
</animated.div>
);
})}
</div>
</div>
<div className="checkout__right">
<h2>SubTotal component</h2>
<SubTotal />
</div>
</div>
);
}
export default Checkout;
Steps to reproduce: Add any product to the basket click on basket icon to go to checkout screen and try to remove items
Here is the github repo with the tutorial code i'm working on.
Is this problem that requires me to force a render?
Thanks
Solution:
Upgraded react spring dependency from 8.0.27 to 9.0.0-rc.3 as suggested by Peter's reply.
And refactored the component as follows us:
import React from "react";
import "./Checkout.css";
import SubTotal from "./SubTotal";
import { useStateValue } from "../StateProvider";
import CheckoutProduct from "./CheckoutProduct";
import shortid from "shortid";
import { useTransition, animated } from "react-spring";
function Checkout() {
const [{ basket, user }] = useStateValue();
const getRandomKey = () => {
return shortid.generate();
};
// define transition behaviour
const transition = useTransition(basket, {
from: { opacity: 0, marginLeft: -100, marginRight: 100 },
enter: { opacity: 1, marginLeft: 0, marginRight: 0 }
});
return (
<div className="checkout">
<div className="checkout__left">
<img
className="checkout__ad"
src="https://images-na.ssl-images-amazon.com/images/G/02/UK_CCMP/TM/OCC_Amazon1._CB423492668.jpg"
alt=""
></img>
<div className="checkout__title">
<h3>Hello, {user?.email}</h3>
<h2>Your shopping basket</h2>
{transition((props, item) => {
const keyNew = getRandomKey();
return (
<animated.div style={props}>
<CheckoutProduct
key={keyNew}
id={item.id}
image={item.image}
price={item.price}
rating={item.rating}
title={item.title}
/>
</animated.div>
);
})}
</div>
</div>
<div className="checkout__right">
<h2>SubTotal component</h2>
<SubTotal />
</div>
</div>
);
}
export default Checkout;
Have you tried with the original key? If you change the key handling strange things can happen.
{transition.map(({ item, key, props }) => {
return (
<animated.div
key={key}
style={props}
className="checkout__product"
>
....
Update:
Also there are some bugs with transition. Try to raise the version number. You can try around 9.0.0-beta.4 or slightly higher. Or you can try 9.0.0-rc.3, but it has a slightly different api. Check the documentation here: https://aleclarson.github.io/react-spring/v9/#Revamped-types