next.js
                                
                                 next.js copied to clipboard
                                
                                    next.js copied to clipboard
                            
                            
                            
                        <Link /> triggers "Maximum update depth exceeded" when child component calls useImperativeHandle
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
    Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 20.6.0: Mon Aug 30 06:12:21 PDT 2021; root:xnu-7195.141.6~3/RELEASE_X86_64
    Binaries:
      Node: 14.16.0
      npm: 6.14.11
      Yarn: 1.22.10
      pnpm: N/A
    Relevant packages:
      next: 12.2.0
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
What browser are you using? (if relevant)
n/a
How are you deploying your application? (if relevant)
n/a
Describe the Bug
When the direct child to Link from next/link calls useImperativeHandle React triggers "Maximum update depth exceeded" and the page crashes.
Expected Behavior
The page renders.
Link to reproduction
https://github.com/JCB-K/next-imperative-hook-bug
To Reproduce
Either clone the repo above, run it and browse to the homepage, or use the code below to repro:
const Link = React.forwardRef((props, ref) => {
  React.useImperativeHandle(ref, () => ({}));
  return <a {...props} />;
});
const WrappedLinkComponent = ({ href, ...rest }) => (
  <NextLink href={href}>
    <Link href={href} {...rest} />
  </NextLink>
);
export default function Home() {
  return <WrappedLinkComponent href="Somewhere">Click</WrappedLinkComponent>;
}
- Bisecting indicates that this commit: 647c93e4d036a9f506cad329e687780be09cafa9 causes the bug.
- I've added a regression test in this commit https://github.com/JCB-K/next.js/commit/5478ce1e59d20d1f80f8b89187ff55cfd3daa446
- Some further debugging indicates that this code causes the bug, or at least that path. All tests pass when startTransitionis undefined.
Got the same error while upgrading from 12.1.2 to 12.2.0
It did not use useImperativeHandle but it was a forwardRef component. React 17
Is there any workarounds you came up with? The imperativeHandle is quite important for me and leads to a lot of problems now.
EDIT: I feel dirty now, but I am just rendering a fake class component that looks like this
// disabled due to https://github.com/vercel/next.js/issues/38293, see ImperativeHandleForNextJsSupport below
// useImperativeHandle(
//   ref,
//   getImperativeHandle
// )
...
return <>
  <ImperativeHandleForNextJsSupport
    ref={ref}
    handle={getImperativeHandle}
  />
  <TheRealChildrenStuff />
</>
which uses the handle function and provides it all via this inside the component