Search code examples
javascriptreactjsreact-spring

Animating scrollTop using react-spring


this should be simple but i think i'm missing something crucial on how Spring works, the documentation is not much of help.

I have a dynamic list, the user can add elements, when that happens i want to use React Spring to animate the scroll to the bottom of the page (identified by currentBottomY variable)

i have something like this

const mainRef = useRef<HTMLElement | null>(null)

const [y, setY] = useSpring({
    from: { y: mainRef?.current?.scrollTop || 0 },
    onFrame: props => {
       mainRef.current.scrollTop = props.y
    },
})

const onAddRow = () => {
    setY({ y: currentBottomY })
}

return (
    <animated.div ref={mainRef}>
        <List />
    </animated.div>
)

I'm getting errors saying i cannot define from and onFrame in there but in the docs it says otherwise, i really cannot make heads or tails on this, any help?


Solution

  • Thanks to Matt's pointer i solved the issue and created a reusable hook that accepts the container's ref and scrolls to the bottom when the scrollToBottom() function is called.

    import { useSpring } from 'react-spring'
    
    const useScrollAnimation = (
      containerRef: React.MutableRefObject<HTMLDivElement | null>
    ): { animate: () => void } => {
      const [, setY] = useSpring(() => ({
        y: 0,
        onFrame: (props: any) => {
          props
        },
      }))
    
      const scrollToBottom = () => {
        setTimeout(() => {
          const current = containerRef?.current
          if (current) {
            const { scrollHeight } = current
            setY({
              config: { duration: 200 },
              y: scrollHeight - current.getBoundingClientRect().bottom,
              onFrame: (props: any) => (current.scrollTop = props.y),
            })
          }
        }, 0)
      }
    
      return { scrollToBottom }
    }
    
    export default useScrollAnimation