[BUG] useScrollLock locks scroll forever in development (React Strict mode)

Author: some1chanCreated Oct 20, 2024Updated Jan 8, 2026
Labelsbug

Describe the bug

Minor bug, but useScrollLock will forever lock in development mode, due to strict mode rerendering useScrollLock, and therefore setting the original state to the body's styling, and then overwriting it to the locking style.

To Reproduce

  • Create a Next.js project with strict mode on

  • Use const { lock, unlock } = useScrollLock({ autoLock: false }) in some component like this:

    typescript
    export default function Test() {
      const { lock, unlock } = useScrollLock({ autoLock: false })
    
      const toggleMenu = () => {
        setIsMenuOpen((value) => {
          if (value) unlock()
          else lock()
          return !value
        })
      }
    
      useEffect(() => {
        function handleKey(event: KeyboardEvent) {
          if (event.key === 'm') toggleMenu()
        }
        document.addEventListener('keyup', handleKey)
        return () => {
          document.addEventListener('keyup', handleKey)
        }
      }, [])
    }
  • Run next dev, and try pressing the m key to toggle the menu.

Expected behavior

For useScrollLock to not lock the scroll in Strict mode.

Additional context

Used Next.js 15.0.0-rc.1, although I don't see Next.js 14 changing this behavior. EDIT: nope it goes away in Next.js v14 even with Strict mode.