freeCodeCamp / classroom

BSD 3-Clause "New" or "Revised" License
143 stars 120 forks source link

2 of 2 React Hydration — Error 2 of 3 errors in Admin view: Unhandled Runtime Error: Error: Hydration failed because the initial UI does not match what was rendered on the server. #360

Closed lloydchang closed 1 year ago

lloydchang commented 1 year ago

Describe the bug 2 of 2 React Hydration — Error 2 of 3 errors in Admin view: Unhandled Runtime Error: Error: Hydration failed because the initial UI does not match what was rendered on the server.

To Reproduce Steps to reproduce the behavior:

  1. Go to Admin view

Expected behavior Error message without the stack trace.

Screenshots 2 of 2 React Hydration — Error 2 of 3 errors in Admin view: Unhandled Runtime Error: Error: Hydration failed because the initial UI does not match what was rendered on the server.

Screen Shot 2023-07-06 at 10 20 34 AM (1)

 2 of 3 unhandled errors

Unhandled Runtime Error
Error: Hydration failed because the initial UI does not match what was rendered on the server.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

Call Stack
throwOnHydrationMismatch
node_modules/react-dom/cjs/react-dom.development.js (12507:0)
tryToClaimNextHydratableInstance
node_modules/react-dom/cjs/react-dom.development.js (12535:0)
updateHostComponent
node_modules/react-dom/cjs/react-dom.development.js (19902:0)
beginWork
node_modules/react-dom/cjs/react-dom.development.js (21618:0)
beginWork$1
node_modules/react-dom/cjs/react-dom.development.js (27426:0)
performUnitOfWork
node_modules/react-dom/cjs/react-dom.development.js (26557:0)
workLoopSync
node_modules/react-dom/cjs/react-dom.development.js (26466:0)
renderRootSync
node_modules/react-dom/cjs/react-dom.development.js (26434:0)
performConcurrentWorkOnRoot
node_modules/react-dom/cjs/react-dom.development.js (25738:0)
workLoop
node_modules/scheduler/cjs/scheduler.development.js (266:0)
flushWork
node_modules/scheduler/cjs/scheduler.development.js (239:0)
MessagePort.performWorkUntilDeadline
node_modules/scheduler/cjs/scheduler.development.js (533:0)

Screen Shot 2023-07-06 at 10 25 16 AM

Desktop (please complete the following information):

Additional context Relates to https://github.com/freeCodeCamp/classroom/issues/134 https://github.com/freeCodeCamp/classroom/issues/359 https://github.com/freeCodeCamp/classroom/issues/361

lloydchang commented 1 year ago

Hi @theGaryLarson @Komal914 @sijin-raj @GuillermoFloresV

If @theGaryLarson and/or @Komal914 are looking for additional issues to solve, I reported: • https://github.com/freeCodeCamp/classroom/issues/359https://github.com/freeCodeCamp/classroom/issues/360 • https://github.com/freeCodeCamp/classroom/issues/361

Thank you!

lloydchang commented 1 year ago

Related information from https://codedayorg.slack.com/archives/C05E350DQH4/p1688894693666219?thread_ts=1688836862.909659

@Komal Kaur @sijin @Gary Larson

If I were in your shoes, below is how I would go about it:

  1. First, I would want clarity about the error messages and their contexts, which are probably at deeper abstraction layers below the surface and user interface.

For example:

Error messages 1 and 2: The hints from the messages may help, specifically the keyword Hydration

Error message 3: The hints from the error message may help, specifically the keyword Boundary

Error messages 1 and 2:

Unhandled Runtime Error

Error: Hydration failed because the initial UI does not match what was rendered on the server.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

Google search of:

Error: Hydration failed because the initial UI does not match what was rendered on the server.

Points to

https://stackoverflow.com/questions/71706064/react-18-hydration-failed-because-the-initial-ui-does-not-match-what-was-render

I have been experiencing the same problem lately with NextJS and i am not sure if my observations are applicable to other libraries. I had been wrapping my components with an improper tag that is, NextJS is not comfortable having a p tag wrapping your divs, sections etc so it will yell "Hydration failed because the initial UI does not match what was rendered on the server". So I solved this problem by examining how my elements were wrapping each other.

Which points to

https://github.com/facebook/react/issues/24519#issuecomment-1122780621

This seems to be expected behavior? SSR cannot work with improper tag nesting as per the HTML spec, the browser's parser won't accept it, and the whole point of SSR is to have the browser parse the initial document structure for you without using any JS. Client side rendering can work with improper tag nesting because the DOM apis do allow creating these invalid nestings "by hand" (with document.createElement, appendChild, etc.).

There is no way to create a raw HTML document that nests a

directly inside a

using static markup, so there's no way to do it with SSR.

So this situation is a warning for client side rendering, an error for SSR, and a warning for hydration; but the only way to continue the "hydration" is to blast away all of the DOM so far because it will be wrong due to invalid nesting.

In error messages 1 and 2, a keyword is Hyrdation.

The referenced web link in error messages 1 and 2 is:

https://nextjs.org/docs/messages/react-hydration-error

Text content does not match server-rendered HTML

Why This Error Occurred

While rendering your application, there was a difference between the React tree that was pre-rendered (SSR/SSG) and the React tree that rendered during the first render in the Browser. The first render is called Hydration which is a feature of React.

This can cause the React tree to be out of sync with the DOM and result in unexpected content/attributes being present.

Possible Ways to Fix It

In general, this issue is caused by using a specific library or application code that is relying on something that could differ between pre-rendering and the browser.

An example of this is using window in a component's rendering.

Another example:

Invalid HTML may cause hydration mismatch such as div inside p.

Error message 3 of 3:

Unhandled Runtime Error

Error: There was an error while hydrating. Because the error happened outside of a Suspense Boundary, the entire root will switch to client rendering.

In error message 3, a keyword is Boundary.

Hence a Google Search for boundary in React leads to:

https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary

Catching rendering errors with an error boundary

By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an error boundary. An error boundary is a special component that lets you display some fallback UI instead of the part that crashed—for example, an error message.

https://nextjs.org/docs/pages/building-your-application/configuring/error-handling

Handling Client Errors

React Error Boundaries is a graceful way to handle a JavaScript error on the client so that the other parts of the application continue working. In addition to preventing the page from crashing, it allows you to provide a custom fallback component and even log error information.

To use Error Boundaries for your Next.js application, you must create a class component ErrorBoundary and wrap the Component prop in the pages/_app.js file. This component will be responsible to:

  • Render a fallback UI after an error is thrown
  • Provide a way to reset the Application's stat
  • Log error information
lloydchang commented 1 year ago

https://github.com/freeCodeCamp/classroom/pull/398 lgtm as a good enough solution because Admin view isn't intended for Search Engine Optimization (SEO). I don't know why the errors were happening in the first place, but it may not matter if Server Side Rendering (SSR) can be disabled for the Admin view.

lloydchang commented 1 year ago

(edited) ~This error no longer happens after #401~

401 is merged and I'm still seeing this, so the fix isn't #401

lloydchang commented 1 year ago

Please contact @GuillermoFloresV if you have further questions about this. Thanks!