/ #javascript #react #node 

Why doesn't React.useEffect run on React server-side renders (SSR)?

Why doesn’t React.useEffect run during a server-side render (SSR) for example when using it inside a Next.js application?

The obvious spots in the docs for information like this are the React docs on useEffect and the React docs on string/static rendering neither of which mention any particular behaviour of useEffect during server-side rendering (SSR).

Table of Contents

When does useEffect run?

The closest to an explanation we find in the React docs on useEffect is that:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

Those 3 methods don’t run during a server-side render (SSR) of a React class component, so it stands to reason that useEffect doesn’t either. The conclusion that React.useEffect doesn’t run during a server-side render (SSR) is left to the reader however. Another interpretation of this tip is that for people familiar with the class component lifecycle, a useful mental shortcut is to think of useEffect as the amalgamation of those 3 methods, not that it strictly complies with how they work.

Here’s a better section of the docs, again note the lack of mention of server-side rendering (SSR):

Does useEffect run after every render? Yes! By default, it runs both after the first render and after every update. (We will later talk about how to customize this.) Instead of thinking in terms of “mounting” and “updating”, you might find it easier to think that effects happen “after render”. React guarantees the DOM has been updated by the time it runs the effects.

That’s the key to explaining why React.useEffect doesn’t run on server-side render (SSR): useEffect runs after the render.

Why doesn’t useEffect run on React SSR?

As we’ve seen in the previous section: useEffect runs after the render.

In the context of useEffect + server-side rendering (SSR), “after the render” is “after we’re done converting the React app into a HTML string”, since we’re not intending to mount our React app.

This post was prompted by the difficulty I found replying to the question: “Why doesn’t React.useEffect run on React server-side renders (SSR)?”

How does one explain that useEffect doesn’t run on a SSR pass?

The @reactjs docs don’t actually mention anything (except a tangential mention about componentDidMount)

The closest I found was a @dan_abramov gist

“it [useEffect] won’t run on the server, but it also won’t warn.”

— Hugo (@hugo__df) February 26, 2021

Thanks to @kentcdodds for his reply.

Your understanding is correct. useEffect happens *after* mount/update, but the server doesn’t mount so it doesn’t happen.

— Kent C. Dodds (@kentcdodds) February 26, 2021

Photo by Krzysztof Kowalik on Unsplash


Hugo Di Francesco

Co-author of "Professional JavaScript", "Front-End Development Projects with Vue.js" with Packt, "The Jest Handbook" (self-published). Hugo runs the Code with Hugo website helping over 100,000 developers every month and holds an MEng in Mathematical Computation from University College London (UCL). He has used JavaScript extensively to create scalable and performant platforms at companies such as Canon, Elsevier and (currently) Eurostar.

Get The Jest Handbook (100 pages)

Take your JavaScript testing to the next level by learning the ins and outs of Jest, the top JavaScript testing library.