Home > Net >  How to remove an element from useSprings array by id
How to remove an element from useSprings array by id

Time:01-16

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)
  );
}
  • Related