Home > Mobile >  Next.js "Text content did not match"
Next.js "Text content did not match"

Time:12-05

I have component in Next.js which displays data pulled from a database, this is all fine. The problem occurs when I attempt to format the dates, I get the following warning Warning: Text content did not match. I roughly understand that it's to do with the client data being out of sync with the server data but I'm not sure the best approach to fix it. I have seen a solution using useEffect but my knowledge of this hook is still a little basic.

My current thinking is to format the dates and then add them to the projects object, then they can be mapped out with the rest of the data, does that sound like a valid idea?

Here's what I currently have:

import { useState, useEffect } from 'react';

export default function ProjectList(props) {
  const [projects, setProjects] = useState(props.projects.data);
  
  // format the date
  function formatStartDate(startDate) {
    return Intl.DateTimeFormat('default', {
      month: 'short',
      day: '2-digit',
      hour: '2-digit',
      minute: '2-digit',
    }).format(new Date(startDate));
  }

  useEffect(() => {
    setProjects(props.projects.data);
  }, [props]);

  return (
    projects.length > 0 && (
      <>
        {projects &&
          projects.map((project) => (
            <div key={project.id}>
              <h2> {project.attributes.project_name}</h2>
              <p>{formatStartDate(project.attributes.start_date)}</p>
            </div>
          ))}
      </>
    )
  );
}

Thanks!

CodePudding user response:

Yes, you are on the right track. On the useEffect, you need to format the dates and update the projects state. This ensures that the dates are correctly formatted on the server side and the client data is in sync with the server data.

import { useState, useEffect } from "react";

export default function ProjectList(props) {
  const [projects, setProjects] = useState(props.projects.data);

  // format the date
  function formatStartDate(startDate) {
    return Intl.DateTimeFormat("default", {
      month: "short",
      day: "2-digit",
      hour: "2-digit",
      minute: "2-digit",
    }).format(new Date(startDate));
  }

  useEffect(() => {
    // format the dates and update the projects state
    const formattedProjects = props.projects.data.map((project) => {
      return {
        ...project,
        attributes: {
          ...project.attributes,
          start_date: formatStartDate(project.attributes.start_date),
        },
      };
    });

    setProjects(formattedProjects);
  }, [props]);

  return (
    projects.length > 0 && (
      <>
        {projects &&
          projects.map((project) => (
            <div key={project.id}>
              <h2> {project.attributes.project_name}</h2>
              <p>{project.attributes.start_date}</p>
            </div>
          ))}
      </>
    )
  );
}
  • Related