I'm using react spring's useSprings hook. My implementation of this hook takes a variable number for the count, and then has an associated configuration.
My hook implementation looks like this:
const [activeTokens, setActiveTokens] = useState([]);
const [tokenSprings, setTokenSprings] = useSprings(activeTokens.length, (index) => {
return {
from: { transform: `translate3d(0px, 0px, 0)`},
to: async (next) => {
var rotate = randomInt(800, 7200);
await next({
transform: `translate3d(1px, 1px, 0)`,
config: { mass: 0.4, tension: 5, friction: 3 },
})
},
}
}
});
I'm able to add tokens and render the springs as expected. The issue I'm running into is when I want to remove specific tokens from the DOM. The jsx looks as follows:
tokenSprings.map((spring, index) => (
<animated.div className="text-white text-2xl absolute cursor-pointer" key={index} style={spring}>
<div onClick={() => handleTokenClick(index)}>
<FontAwesomeIcon icon={faMoneyBill}></FontAwesomeIcon>
</div>
</animated.div >
My handleTokenClick
function looks as follows:
function handleTokenClick(tokenId) {
setActiveTokens(activeTokens => activeTokens.filter(token => token.id !== tokenId));
}
This obviously won't work, because I do not have any token.id
accessible from the tokenSprings
array. I scoured react spring docs, but I could not find a way to include an id that i'd specify in the tokenSprings
array for each element, that i can later reference in the jsx.
Is this possible? If not, how is it best to reference the actual tokenSpring
element which I want to remove from DOM?
CodePudding user response:
Seem you have mistake, in line <div onClick={() => handleTokenClick(index)}>
you passed index array to param of handleTokenClick
, but when you define function function handleTokenClick(tokenId)
you assigned name for param is tokenId
instead index
. I mean you was confused between tokenId
and index
[Solve] So, you shoud modify define function handleTokenClick
:
function handleTokenClick(index) {
const cloneActiveTokens= activeTokens; // clone Active Token
cloneActiveTokens.splice(index, 1); // remove 1 element from index, array will be mutated
setActiveTokens(cloneActiveTokens);
}
CodePudding user response:
There does appear to be a mixup in what the argument passed to the handleTokenClick
callback handler represents.
handleTokenClick
is coded to take a token id for filtering purposes
function handleTokenClick(tokenId) {
setActiveTokens(activeTokens => activeTokens.filter(
token => token.id !== tokenId)
);
}
but is passed the mapped array index
tokenSprings.map((spring, index) => (
<animated.div
className="text-white text-2xl absolute cursor-pointer"
key={index}
style={spring}
>
<div onClick={() => handleTokenClick(index)}> // <-- index is passed
<FontAwesomeIcon icon={faMoneyBill} />
</div>
</animated.div>
))
Unless any of the element objects in the activeTokens
array happen to have id
properties that match an array index, it's likely that the filter condition will always evaluate false and no element is removed from the array.
To resolve you should refactor the handleTokenClick
handler to take an index and filter by the index value.
const handleTokenClick = (tokenIndex) {
setActiveTokens(activeTokens => activeTokens.filter(
(token, index) => index !== tokenIndex)
);
}