Next.js Discord

Discord Forum

Clock component with setTimeout causes problems with App router

Answered
Pacific anchoveta posted this in #help-forum
Open in Discord
Pacific anchovetaOP
Hi, everyone.

I just made a little Clock component, which looks like this:

"use client"
import { useState } from "react"

export function Clock() {
  let time = new Date().toLocaleTimeString()

  const [ctime, setTime] = useState(time)
  const UpdateTime = () => {
    time = new Date().toLocaleTimeString()
    setTime(time)
  }
  setInterval(UpdateTime)
  return <h1>{ctime}</h1>
}


This causes a couple of errors, although it seems to work, it's just a warning in the left corner. It seems to be connected to the server rendering. I run Next 13.5.5 with the App router.

This is the error message:
Error: Text content does not match server-rendered HTML. Warning: Text content did not match. Server: "2:34:42 PM" Client: "14:34:44"

Any ideas what causes this, or what I'm not compensating for?
Answered by Giant panda
Even though you fixed the usage of setInterval and cleaning it up properly the initial value is still different. During prerendering and client-side rendering new Date() gets evaluated which should not happen. Make the initial value undefined or similar value that is equal across environments then you will no longer have a hydration error and the client can set it with the first tick after mounting.
View full answer

14 Replies

Barbary Lion
import { useState, useEffect } from "react";

export function Clock() {
const [ctime, setCtime] = useState(new Date().toLocaleTimeString());

// Use useEffect //
useEffect(() => {
const intervalId = setInterval(() => {
const newTime = new Date().toLocaleTimeString();
setCtime(newTime);
}, 1000);
// clear clearInterval on return callback
return () => {
clearInterval(intervalId);
};
}, []);

return <h1>{ctime}</h1>;
}
Um, did it work?
Or same error?
Ofc you need to still use "use client" at top
Pacific anchovetaOP
Hey, @Clown and @Barbary Lion . Thanks for the suggestion - unfortunately the errors persists. I used your code @Barbary Lion , but the errors are still the same:

Error: Text content does not match server-rendered HTML. Warning: Text content did not match. Server: "3:55:54 PM" Client: "15:55:56"

and

Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.
Barbary Lion
'use client'
add at first line
Pacific anchovetaOP
Hey, @Barbary Lion I got it there. It was always there, but thanks for the input 🙂
Pacific anchovetaOP
Just to be clear, I still got the errors 🙂
Barbary Lion
ohh🙁
okay can u pleases send your componet code or try to send a file.
@Pacific anchoveta
@Pacific anchoveta Just to be clear, I still got the errors 🙂
Giant panda
Even though you fixed the usage of setInterval and cleaning it up properly the initial value is still different. During prerendering and client-side rendering new Date() gets evaluated which should not happen. Make the initial value undefined or similar value that is equal across environments then you will no longer have a hydration error and the client can set it with the first tick after mounting.
Answer
Pacific anchovetaOP
@Giant panda thanks a lot, that worked