Issue found in Next.js 14: Hydration Error | Caution: Client Components can only receive plain objects from Server Components

I'm currently in the process of creating an application using Next.js 14, TypeScript, Mongoose, and MongoDB.

In this app, I retrieved user data from my database and displayed them on cards along with relevant information like tags represented by badges.

To make these cards and badges clickable, I utilized the Link component.

Here is a snippet of the pertinent code:

  • "components\cards\UserCard.tsx":
/* The code for UserCard component goes here... */
  • "components\shared\RenderTag.tsx":
/* The RenderTag component code can be found here... */

Despite my efforts, I encountered the following error:

Error: Hydration failed due to a mismatch between the server-rendered UI and the initial state. For more details, refer to: https://nextjs.org/docs/messages/react-hydration-error

The expected matching <article> element was not found in the server-side HTML.

I attempted various solutions such as replacing the article with a div or using the suppressHydrationWarning property, but none resolved the issue.

As an alternative, I switched to utilizing useRouter instead of Link for navigation.

Here is the revised code:

  • "components\shared\RenderTag.tsx":
/* The updated RenderTag component code resides here... */

Although the hydration error has been eliminated, a new warning surfaced in the terminal:

Warning: Only plain objects are supported in Client Components when passed from Server Components. Objects with toJSON methods are not compatible. Convert complex objects to simple values before passing them as props.
<... _id={{buffer: ...}} name="next.js">

Why is this warning occurring, particularly the segment

<... _id={{buffer: ...}} name="next.js">
?

This issue appears to stem from the "tags" collection in my database which contains entries like:

{"_id":{"$oid":"66a476d397749b79a8140e72"},"__v":{"$numberInt":"0"},"createdOn":{"$date":{"$numberLong":"1722054355742"}},"followers":[],"name":"next.js","questions":[]}
{"_id":{"$oid":"66a5164197749b79a8a3258b"},"__v":{"$numberInt":"0"},"createdOn":{"$date":{"$numberLong":"1722095169919"}},"followers":[],"name":"React","questions":[]}

However, why does this error surface only when using useRouter?

Answer №1

Upon reviewing your initial code snippet: The issue arises from nesting the RenderTag component within a Link component, which in turn is contained within another Link component. This can lead to navigation errors when attempting to access different URLs, such as navigating to /etiquettes/${_id} and ending up at /profile/${user.clerkId}. To resolve this hydration error, consider removing the overarching Link component from the UserCard and instead wrapping individual elements like divs, Images, and other components inside their own respective Link components. However, exclude the RenderTag component from being wrapped in a Link, thus ensuring the hydration error does not occur. Here is an example:

/* imports and type declarations */
const UserCard = async ({ user }: Props) => {
  const interactedTags = await getTopInteractedTags({ userId: user._id });

  return (
    <div
      className="shadow-light100_darknone w-full max-xs:min-w-full xs:w-[260px]"
    >
      <article className="background-light900_dark200 light-border flex w-full flex-col items-center justify-center rounded-2xl border p-8">

    <Link href={`/profile/${user.clerkId}`}>
        <Image
          src={user.picture}
          alt="image profil utilisateur"
          width={100}
          height={100}
          className="rounded-full"
        />
    </Link> {/* Repeat for other divs except RenderTag */}

        <div className="mt-4 text-center">
          <h3 className="h3-bold text-dark200_light900 line-clamp-1">
            {user.name}
          </h3>
          <p className="body-regular text-dark500_light500 mt-2">
            @{user.username}
          </p>
          {/* {user.orgId && (
            <p className="body-regular text-dark500_light500 mt-2">
              Org ID: {user.orgId}
            </p>
          )} */}
        </div>

        <div className="mt-5"> {/* Ensure no <Link/> wrapping here */}
          {interactedTags.length > 0 ? (
            <div className="flex items-center gap-2">
              {interactedTags.map((tag) => (
                <RenderTag key={tag._id} _id={tag._id} name={tag.name} />
              ))}
            </div>
          ) : (
            <Badge>Pas encore d’étiquettes</Badge>
          )}
        </div>
      </article>
    </div>
  );
};

export default UserCard;

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to update JSON data through a post request without it getting added to the existing data?

Hello, I am currently delving into Angular2 and encountering a problem concerning RestAPI. When I send a post request to the server with a JSON file, I intend to update the existing data in the JSON file; however, what actually happens is that the new data ...

The case-insensitive flag 'i' is ineffective when using JQuery to filter data

I am trying to filter a list based on a search string while maintaining case insensitivity. However, I encountered an issue where the i flag for case-insensitivity works in a normal jQuery selector, but not in the filter selector. Could this be a bug or is ...

Converting coordinates to pixel-based fixed positioning in CSS

After creating an animated square pie chart using basic CSS to display it in a grid format, I am now looking to transform the larger squares into a state map grid. Any ideas on how to achieve this? In my JavaScript code snippet below, I believe there is a ...

Delete the class when the user clicks anywhere on the page

I have 2 buttons that will toggle/remove a class when the user clicks on them. $('.social-toggle').on('click', function() { $('.social-networks').not($(this).next()).removeClass('open-menu') $(this).next().toggl ...

Retrieving the ID from the element that was clicked

Here is a code snippet that allows for the changing of color and text when an href link is clicked. /* Function to change the color of the button upon click */ function changeColor(element) { alert(element.target.id); if (element.innerHTML == "Selec ...

Capturing member function details using JSDoc

Here's the code snippet I'm working with: /** This class blah blah... @constructor **/ my.namespace.ClassA = function(type) { /** This function performs an action **/ this.doSomething = function(param){ } } The class will be inc ...

Extracting a list from a Bson Document: A step-by-step guide

I'm encountering an issue when attempting to extract a list from a MongoDB document retrieved using the following function: mongoDbAccess.getCollection(collection).find(params).projection(projection); The problem lies in my document which contains a ...

Client-Side Isomorphic JS: A Guide to Using HTTP Requests

Seeking advice on data population for isomorphic flux apps. (Using react, alt, iso, and node but principles are transferable) In my flux 'store' (), I need to fetch data from an api: getState() { return { data : makeHttpRequest(url) ...

Dynamic property access using optional chaining in JavaScript

My attempt to utilize optional chaining, a feature provided by TypeScript for safely accessing dynamic properties, seems to be invalid. export const theme = { headers: { h1: { }, h6: { color: '#828286' }, }, } console.in ...

Utilizing AJAX to integrate the Google Maps Direction API

Currently, I am developing a small website that utilizes the Google Maps API and AJAX to load directions based on selected locations from a dropdown menu. The database stores latitude and longitude coordinates of various locations, which are retrieved via ...

My attempt at creating a straightforward sorting function turned out to be ineffective

My attempt at creating a basic sorting function seems to be failing as it is still returning the original list instead of the sorted one. function sortByPopular (collection) { let items = collection.slice(); items.sort(function(a,b) { re ...

What is the best way to send these values to a JavaScript function and show them one by one on an HTML webpage?

There are 100 values stored in the database. https://i.stack.imgur.com/584Op.jpg I need to retrieve these values from the database using PHP and pass them to JavaScript using Ajax. PHP CODE: for($i=0;$i<=9;$i++) { $random = (10 * $i) + rand(1,10); ...

Issue with nested directive not triggering upon page load

I recently started working with AngularJS and came across an issue with nested directives. In my project, I have two directives: MainDir.js (function(){angular.module("mod").directive("mainDir", function(){ return { restrict: "E", scope: {}, ...

Seeking assistance with producing results

Is there someone who can provide an answer? What will be the output of the code snippet below when logged to the console and why? (function(){ var a = b = 3; })(); console.log("Is 'a' defined? " + (typeof a !== 'u ...

"Incorporate information from a separate VueJs object to enhance your data analysis

Just a quick question here. I have an object with the following value: data() { return { nation: { CZ: require("../../../../../svg/czech-flag.svg"), } }; }, Then I have an API object (FYI, the API is working fine) doctor ...

JavaScript: Obtaining a Distinct Identifier for Various Replicated Entries

Imagine we have an object: var db = [ {Id: "201" , Player: "Jon",price: "3.99", loc: "NJ" }, {Id: "202", Player: "Sam",price: "4.22", loc: "PA" }, {Id: "203" ,Player: "Sam",price: "4.22", loc: "NY" }, {Id: "204", Player: ...

What is the best way to deactivate unclicked href links within a loop?

https://i.sstatic.net/sUufY.png Looking at the template image, my goal is to disable all links that were not clicked when one of the links from 'number1' to 'number3' is clicked. For example, if 'number2' is clicked, then &ap ...

AngularJS: iterating through POST requests and passing each index into its corresponding response

Using AngularJS, I am attempting to execute multiple http POST requests and create an object of successfully finished requests. Here is a sample code snippet: var params = [1, 2, 3], url, i, done = {}; for (i in params) { url = '/dir ...

Create a basic chart using JavaScript

I am looking to replicate a specific chart using JavaScript. The red point in the chart is variable. So far, I have attempted to create it using the flot library: var d3 = [[7,7]]; $.plot("#placeholder", [{ data: d3, points: { show: true } }], { ...

The form will not pass validation

The validation of my form is not working correctly, as all my functions are called when the submit button is clicked. // Main Function function validate_form(form) { var complete = false; // Ensure that only one error message is displayed at a ti ...