@jialin.huang
FRONT-ENDBACK-ENDNETWORK, HTTPOS, COMPUTERCLOUD, AWS, Docker
To live is to risk it all Otherwise you are just an inert chunk of randomly assembled molecules drifting wherever the Universe blows you

© 2024 jialin00.com

Original content since 2022

back
RSS

use client doesn't guarantee complete client-side rendering

Finding issue

I tried to add window to the dependencies of a useEffect hook in a component declared with use client, but found it's not allowed during next build.

This will throw an error:

'use client'
import { memo, useEffect } from 'react'

const ClientComponent = memo<ReactProps>(function ClientComponent({}) {

  useEffect(() => {}, [window])

  return (
  // ...
	)
})

This builds normally with next build:

  useEffect(() => {
    window.scrollX
  }, [])

Explanation of case differences

  • Case 1: dependencies are processed during server-side build, i.e., in a Node.js environment, which naturally doesn't know what window is.
  • Case 2: The callback inside useEffect is executed on the client-side, so it can access browser or client-side environment, hence no issues.

Concept reset

Going back to the first line of the file, I initially thought use client meant this entire file is client-side business, but unexpectedly, SSR (including SSR, SSG) also pays attention to this file during build, causing confusion.

If we reorganize the original concept of use client, we can say:

"I'm just declaring that the imports and stuff inside are client-side modules, but it doesn't mean I can completely ignore server-side behavior.

We usually perceive the browser as the client-side, leading us to believe we can freely use browser-specific APIs like window anywhere in components declared with use client.

But window isn't a client-side module in the semantic sense; it's the browser's global object, and more importantly, it's relevant at runtime rather than build time.

Although the error occurs because the Node.js environment can't recognize window, it also makes me realize the concept behind use client. Even with use client declared, it doesn't change JavaScript's inherent behavior or build-time constraints.

References

https://github.com/reactwg/server-components/discussions/4

https://stackoverflow.com/questions/75692116/next-js-13-window-is-not-defined

EOF