next.js icon indicating copy to clipboard operation
next.js copied to clipboard

<Link /> triggers "Maximum update depth exceeded" when child component calls useImperativeHandle

Open JCB-K opened this issue 3 years ago • 3 comments

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>;
}


JCB-K avatar Jul 04 '22 11:07 JCB-K

  • 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 startTransition is undefined.

JCB-K avatar Jul 04 '22 13:07 JCB-K

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

kevinsimper avatar Jul 06 '22 21:07 kevinsimper

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

EyMaddis avatar Nov 10 '22 19:11 EyMaddis