mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
### What When you have bad nesting html in your React code, React wil raise hydration error since the browser html parser might parse it to sth else different comparing to server html on client. Previously we're display only the warning in the error description in dev overlay. Now we introduced another format of displaying pesudo html that representing your code, with highlighting the html tag that causes the error. Since React might gives you the whole component stack of React tree, so we also introduced a way that can collapse the error. #### Example https://github.com/vercel/next.js/assets/4800338/622122d6-4d2e-4c8e-95e8-4864343e478b ### Why The reason we added this is that even we show the html diff, it could super large due to React ordering the html on client, so the mismatch might be a lot. The idea here is similar to what you saw when you passed down a bad event handler into server component, we displayed a pesudo html as it could hit your mind faster than just seeing the warning. The best way is to display the source code, but before we can show the source, getting component stack display as pseudo html instead of here could be more helpful. ### After vs Before <img width="400" src="https://github.com/vercel/next.js/assets/4800338/714119ad-ff23-46a9-bc5a-5601eb390e71"> <img width="400" src="https://github.com/vercel/next.js/assets/4800338/575f95fa-889e-4cee-ad19-9c2fea06519a"> Closes NEXT-2621
68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
/* eslint-env jest */
|
|
import { sandbox } from 'development-sandbox'
|
|
import { FileRef, nextTestSetup } from 'e2e-utils'
|
|
import { outdent } from 'outdent'
|
|
import path from 'path'
|
|
|
|
describe('Error overlay for hydration errors', () => {
|
|
const { next } = nextTestSetup({
|
|
files: new FileRef(path.join(__dirname, 'fixtures', 'default-template')),
|
|
dependencies: {
|
|
react: 'latest',
|
|
'react-dom': 'latest',
|
|
},
|
|
skipStart: true,
|
|
})
|
|
|
|
it('should show correct hydration error when client and server render different text', async () => {
|
|
const { cleanup, session, browser } = await sandbox(
|
|
next,
|
|
new Map([
|
|
[
|
|
'index.js',
|
|
outdent`
|
|
const isClient = typeof window !== 'undefined'
|
|
export default function Mismatch() {
|
|
return (
|
|
<div className="parent">
|
|
<main className="child">{isClient ? "client" : "server"}</main>
|
|
</div>
|
|
);
|
|
}
|
|
`,
|
|
],
|
|
])
|
|
)
|
|
|
|
expect(await session.hasRedbox()).toBe(true)
|
|
|
|
expect(await session.getRedboxDescription()).toMatchInlineSnapshot(`
|
|
"Error: Text content does not match server-rendered HTML.
|
|
See more info here: https://nextjs.org/docs/messages/react-hydration-error"
|
|
`)
|
|
|
|
expect(await session.getRedboxDescriptionWarning()).toMatchInlineSnapshot(
|
|
`"Text content did not match. Server: "server" Client: "client""`
|
|
)
|
|
|
|
await session.patch(
|
|
'index.js',
|
|
outdent`
|
|
export default function Mismatch() {
|
|
return (
|
|
<div className="parent">
|
|
<main className="child">Value</main>
|
|
</div>
|
|
);
|
|
}
|
|
`
|
|
)
|
|
|
|
expect(await session.hasRedbox()).toBe(false)
|
|
|
|
expect(await browser.elementByCss('.child').text()).toBe('Value')
|
|
|
|
await cleanup()
|
|
})
|
|
})
|