Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with Next.js ^14.0.2 in DEV environment #247

Closed
andre-lergier opened this issue Nov 24, 2023 · 5 comments
Closed

Issue with Next.js ^14.0.2 in DEV environment #247

andre-lergier opened this issue Nov 24, 2023 · 5 comments
Assignees

Comments

@andre-lergier
Copy link

Since updating Next.js from v14.0.1 to v14.0.2 and v14.0.3 the useResizeDetector() hook is no more working in the local development environment.

On the initial render the hook always returns undefined.
If I edit the component after it's first render and the dev server triggers a rerender, the hook returns the correct values.

This can be simulated with the following code:

export function NavigationMenuBar() {
  const { height: menuBarHeight, ref: menuBarRef } = useResizeDetector();

  useEffect(() => {
    console.log('menuBarHeight', menuBarHeight);

    document.documentElement.style.setProperty(
      '--navigation-menu-bar-height',
      `${Math.floor(menuBarHeight || 0)}px`,
    );
  }, [menuBarHeight]);

  return (
      <nav ref={menuBarRef}>Nav</nav>
  );
}

In the production build or with Next.js v14.0.1 everything is working as expected.

I know that this might be a Next.js issue, but I currently don't understand what could cause this problem - so it's difficult to me to open an issue there.

@SiddharthPant
Copy link

SiddharthPant commented Nov 25, 2023

Same issue for me as well. Also I noticed that if I make a change in the file where I have useReactDetector and nextjs dev server reloads on its own, then useReactDetector works and returns width. But when I then try to manually refresh or load the page it returns undefined every time. Like OP said this only happens in NextJS 14.0.2+, when I use 14.0.1 everything works.

@brstreet2
Copy link

I'm having the same issue as well, I'm using Next.js 14.0.3. I had to downgrade my Next.js project to 14.0.1 and it worked like a charm.

@zophiana
Copy link

zophiana commented Dec 1, 2023

I've already opened an issue at nextjs vercel/next.js#58767

I have already debugged it a bit, here are my findings:

  • it was introduced by a commit in nextjs which pulled react changes
  • it is caused by the react strict mode, but only since nextjs v14.0.2, disabling it solves the problem or the prod build
  • you can quick fix it in react-resize-detector by commenting this out:
return () => {
  // component is unmounted
  // clear ref to avoid memory leaks
  // setRefElement(null); // <= comment to quick-fix it
  onRefChange.current = null;
};
  • It also seems that since v14.0.2 the setRefElement function is only called twice. The first time it sets the ref right, the second time it sets the ref to null, triggered by the code above. That's why commenting out that line works, because it can't set the ref to null.
  • In v14.0.1 this function is called at least 3 or 4 times, I can't remember. But the important thing is that after setting it to null the second time, it gets set correctly the third time.

As a side note I am pretty new to the hole JS/TS ecosystem so I don't fully understand all of it, but that's are my findings. I hope they might help.

@snelsi
Copy link
Collaborator

snelsi commented Dec 1, 2023

@maslianok Please, take a look when you have time

@maslianok
Copy link
Owner

In version 9.1.1:

React's strict mode causes components to render twice in development, as described here: React StrictMode Documentation. This also means that the logic for mounting and unmounting in useEffect is executed twice.

However, there's an issue with ref callbacks: they are only triggered once before the first unmount. As a result, it's not possible to remove the reference to the DOM node during unmount because the reference is no longer accessible afterward.

During my tests, I observed no memory leaks even after removing part of the unmount logic. We still maintain the "observer" cleanup, and React handles the removal of DOM references from the state.

Please upgrade to version 9.1.1 and inform me if any issues persist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants