DEV Community

Jade Chou
Jade Chou

Posted on

NextJS Codebase Analysis(3) - how's server props and static props work?

As we all know, Server Components are not allowed to use hooks like useState and useEffect—but why?


🚧 Understanding the Request Flow

Let’s start from a typical page request. When a request comes in (and possibly hits the cache), it flows through several key functions:

  • handleResponse
  • doRender
  • renderToHTMLOrFlightImpl
  • generateCacheEntry

👉 generateCacheEntry is the core of Next.js caching strategy.


🔑 Key Parameters in generateCacheEntry

From the function signature, we can identify some critical parameters:

  • encodeCacheKeyParts
  • fn (the actual render function)


🧩 Cache Keys and Server References

Taking a deeper look at encodeCacheKeyParts, we notice something important:

It generates keys that match those in server-reference-manifest.json.

This connects directly to concepts discussed in the previous article.

  • Each page/component has a corresponding cache key
  • These keys are heavily used across Next.js internals


⚙️ The Core Execution: generateCacheEntryImpl

Continuing down the call stack, we reach:

generateCacheEntryImpl — where rendering actually happens

Here, we encounter a key variable:

  • requestPromise

💡 This is crucial:

  • Server Components can be async functions
  • requestPromise represents the execution of the component itself
  • Once resolved, the result is streamed to the client


⏱️ Cache Expiration Strategy

Next.js also implements a time-based cache invalidation strategy:

  • When cache is invoked:
    • It calculates the current time
    • Compares it with the expiration time defined by the developer
  • Based on this, it decides:

Should we reuse the cache or regenerate it?


🗂️ Cache Retrieval

Cache entries are retrieved using:

  • Page key
  • Page path (serializedCacheKey)

📌 Example

For the URL:

http://localhost:3000/blog/2
Enter fullscreen mode Exit fullscreen mode
  • The dynamic parameter:
  {"id": 2}
Enter fullscreen mode Exit fullscreen mode

This value becomes part of the cache key

🧠 So… Why No Hooks in Server Components?

Now that we understand the flow, the reason becomes clearer:

Server Components are designed to be pure, stateless, and cacheable.

Hooks like useState and useEffect:

  • Depend on client-side lifecycle
  • Require persistent state between renders

But Server Components:

  • Are executed once per request (or cache hit)
  • Produce a deterministic output
  • Are serialized and streamed

👉 Allowing hooks would break caching, determinism, and streaming guarantees.


✅ Key Takeaway

Server Components trade interactivity for performance and scalability.

They work because they are:

  • Stateless
  • Deterministic
  • Cache-friendly

And that’s exactly why hooks like useState and useEffect are not allowed.

Top comments (0)