"use client";
import { useEffect, useState } from "react";
const useWindowWidth = (delay = 100): number => {
const [windowWidth, setWindowWidth] = useState(window.innerWidth);
useEffect(() => {
...
}, []);
return windowWidth;
};
export default useWindowWidth;
Why does this hook run on the server if "use client"
is added? It doesn’t cause the application to crash, everything works as the error doesn’t exist, it just logs the error mentioned in the title at the const [windowWidth, setWindowWidth] = useState(window.innerWidth);
line on the window
object.
This is from the official Next.js docs:
Using Client Components in Next.js
To use Client Components, you can
add the React "use client" directive at the top of a file, above your
imports."use client" is used to declare a boundary between a Server and Client
Component modules. This means that by defining a "use client" in a
file, all other modules imported into it, including child components,
are considered part of the client bundle – and will be rendered by
React on the client.
2
Answers
According to this discussion, the
"use client"
only means that it also runs on the client. You can useuseEffect
to access thewindow
object without any errors.Client components will run in the client BUT will be rendered firstly in the server.
What does that mean?
The component with
"use client"
directive is running in the browser and able to use client APIs likewindow
. But, at the first render, It’ll be executed in the server without interactivity to make it render fast.What is the problem with your component?
You initialized useState with
window.innerWidth
which is not accessible in the server so, you will get an error sayingcannot read property of undefined. reading window
.How to fix it?
Use the window within
use(Layout)Effect
. theuseEffect
hook with empty dependency array delays the callback function until the first render is completed.Use
client-only
in your component so it won’t be rendered in the server anymore:This trick is straightforward. It just throws an error on the server so It will redirect it to the client boundary.