mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
We need to handle ref cleanups in a way that is compatible with React 18 and 19. Forking these into -pages (18) and -app (19). Combining them into a single app lead to a different behavior with regards to preload.
54 lines
1.3 KiB
JavaScript
54 lines
1.3 KiB
JavaScript
'use client'
|
|
import React from 'react'
|
|
import Link from 'next/link'
|
|
import { useCallback, useRef, useEffect, useState } from 'react'
|
|
import { flushSync } from 'react-dom'
|
|
|
|
export default function Page() {
|
|
const [isVisible, setIsVisible] = useState(true)
|
|
|
|
const statusRef = useRef({ wasInitialized: false, wasCleanedUp: false })
|
|
|
|
const refWithCleanup = useCallback((el) => {
|
|
if (!el) {
|
|
console.error(
|
|
'callback refs that returned a cleanup should never be called with null'
|
|
)
|
|
return
|
|
}
|
|
|
|
statusRef.current.wasInitialized = true
|
|
return () => {
|
|
statusRef.current.wasCleanedUp = true
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
const timeout = setTimeout(
|
|
() => {
|
|
flushSync(() => {
|
|
setIsVisible(false)
|
|
})
|
|
if (!statusRef.current.wasInitialized) {
|
|
console.error('callback ref was not initialized')
|
|
}
|
|
if (!statusRef.current.wasCleanedUp) {
|
|
console.error('callback ref was not cleaned up')
|
|
}
|
|
},
|
|
100 // if we hide the Link too quickly, the prefetch won't fire, failing a test
|
|
)
|
|
return () => clearTimeout(timeout)
|
|
}, [])
|
|
|
|
if (!isVisible) {
|
|
return null
|
|
}
|
|
|
|
return (
|
|
<Link href="/" ref={refWithCleanup}>
|
|
Click me
|
|
</Link>
|
|
)
|
|
}
|