Search code examples
javascriptreactjsreact-spring

useTransition is not working with my code - TypeError: Cannot read property 'text' of undefined


I'm using React-Spring useTransition and getting error :

TypeError: Cannot read property 'text' of undefined

import React, { useState } from 'react'
import { useSpring, useTransition, animated } from 'react-spring'


function MyApp() {

  const [items, setItems] = useState([
    { id: 1, text: 'Item1' }, { id: 2, text: 'Item2' }
  ]);


  const transition = useTransition(items, item => item.id, {
    from: { opacity: 0, marginLeft: -100, marginRight: 100 },
    enter: { opacity: 1, marginLeft: 0, marginRight: 0 }
  })

  return (
    <>
      <div>
        {transition.map(({ item, key, props }) =>
          <animated.div key={key} style={props}>{item.text}</animated.div>
        )}

      </div>

    </>
  )
}

export default MyApp

enter image description here

What am I doing wrong?


Solution

  • I assume you're installing react-spring without specifying a version, so you're probably getting v9 now. V9 has some breaking changes to it, which unfortunately are not reflected in the documentation. But do check out this explanation.

    The long and short of it is that useTransition, is totally different now. Instead of mapping from transitions, transitions can be called as a function that will return a fragment that you can render. I edited your code a bit to reflect that:

    import { useTransition, animated } from "react-spring";
    
    function App() {
      const [items, setItems] = useState([
        { id: 1, text: "Item1" },
        { id: 2, text: "Item2" }
      ]);
    
      const transition = useTransition(items, {
        from: { opacity: 0, marginLeft: -100, marginRight: 100 },
        enter: { opacity: 1, marginLeft: 0, marginRight: 0 }
      });
    
      const fragment = transition((style, item) => {
        return <animated.div style={style}>{item.text}</animated.div>;
      });
    
      return (
        <>
          <div>{fragment}</div>
        </>
      );
    }
    
    export default App;
    

    Check out this sandbox to play around with it. Because it's only transitioning when it's first rendered, you'll have to hit reload to see the item names slide in from the left.