Search code examples
reactjsreact-spring

How to execute two animations sequentially, using react-spring?


I tried chaining two springs (using useChain), so that one only starts after the other finishes, but they are being animated at the same time. What am I doing wrong?

import React, { useRef, useState } from 'react'
import { render } from 'react-dom'
import { useSpring, animated, useChain } from 'react-spring'

function App() {
  const [counter, setCounter] = useState(0)
  const topRef = useRef()
  const leftRef = useRef()
  const { top } = useSpring({ top: (window.innerHeight * counter) / 10, ref: topRef })
  const { left } = useSpring({ left: (window.innerWidth * counter) / 10, ref: leftRef })

  useChain([topRef, leftRef])

  return (
    <div id="main" onClick={() => setCounter((counter + 1) % 10)}>
      Click me!
      <animated.div id="movingDiv" style={{ top, left }} />
    </div>
  )
}

render(<App />, document.getElementById('root'))

Here's a codesandbox demonstrating the problem: https://codesandbox.io/s/react-spring-usespring-hook-m4w4t


Solution

  • I just found out that there's a much simpler solution, using only useSpring:

    function App() {
      const [counter, setCounter] = useState(0)
    
      const style = useSpring({
        to: [
          { top: (window.innerHeight * counter) / 5 },
          { left: (window.innerWidth * counter) / 5 }
        ]
      })
    
      return (
        <div id="main" onClick={() => setCounter((counter + 1) % 5)}>
          Click me!
          <animated.div id="movingDiv" style={style} />
        </div>
      )
    }
    

    Example: https://codesandbox.io/s/react-spring-chained-animations-8ibpi