Search code examples
reactjstypescriptnext.jsnext.js13hydration

Nextjs use client cannot access <Component> before initialization


I have what I consider to be a fairly straightforward use case in Nextjs, that is, a NavigationBar component with a search input.

<div className="w-full flex flex-row items-center py-5 justify-between">
    <div className="w-40">
      <Link href="/">
        <Image
          className="mx-5"
          src="images/logomark.svg"
          width={100}
          height={32}
          alt={"logo"}
        />
      </Link>
    </div>
    <SearchBar />
</div>

However I recently added use client; to the top of it in preparation to make it stateful. Immediately it began to throw ReferenceError: Cannot access 'NavigationBar' before initialization.

Using the process of elimination I found the culprit to be <SearchBar />, which was stateful and had use client; in it. If I removed SearchBar, it would render.

I am wondering what within SearchBar was causing this issue, so again I removed everything to try to get it not to error. I removed use client;, removed all logic, and replaced the return with a simple <div />. It still throws the error.

Updated SearchBar component:

export const SearchBar = () => {
  return <div />;
};

At this point it is completely unclear to me what could be causing this issue. I assume there is something related to hydration, perhaps HTML semantics, but it is not clear what or how to debug this.

There is also a runtime stack trace:

Uncaught (in promise) ReferenceError: Cannot access 'NavigationBar' before initialization

Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.

The above error occurred in the <NotFoundErrorBoundary> component:

Uncaught Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

Solution

  • SearchBar.js

    'use client'
    const SearchBar = () => {
      return (
        <div>
        </div>
      );
    };
    
    export default SearchBar;
    

    in NavigationBar.js

    import SearchBar from './SearchBar'
    <div className="w-full flex flex-row items-center py-5 justify-between">
        <div className="w-40">
          <Link href="/">
            <Image
              className="mx-5"
              src="images/logomark.svg"
              width={100}
              height={32}
              alt={"logo"}
            />
          </Link>
        </div>
        <SearchBar />
    </div>
    

    Could you try doing it this way? You seem to have a problem creating and importing. Try "export default SearchBar" and see if your import is correct. I would appreciate it if you let me know if it works or not.