Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hydration mismatch after SSR using useMediaQuery #1230

Closed
teaguestockwell opened this issue Apr 12, 2022 · 6 comments · Fixed by #1244
Closed

Hydration mismatch after SSR using useMediaQuery #1230

teaguestockwell opened this issue Apr 12, 2022 · 6 comments · Fixed by #1244

Comments

@teaguestockwell
Copy link
Contributor

What package has an issue

@mantine/hooks

Describe the bug

Hello, I have had an incredible time using Mantine and really appreciate all the incredible work the team has done putting this together for the community!

I came across this issue using useMedaQuery from @mantine/hooks that I was familiar with from another package. I wanted to point this out here in case support for SSR is on the roadmap. Here is repro using nextjs

npx create-next-app@latest

index.tsx

import type { NextPage } from 'next'
import { useMediaQuery } from '@mantine/hooks'

const Home: NextPage = () => {
  const md = useMediaQuery('(min-width: 1000px)')
  console.log(md, typeof window === 'undefined' ? 'server' : 'client')
  return <span>{String(md)}</span>
}

export default Home

Screen Shot 2022-04-11 at 17 32 59

The SSR of useMediaQuery has an initial state of false where the client defaults to the result of the media query: true

In which browser did the problem occur

chrome

If possible, please include a link to a codesandbox with the reproduced problem

No response

Do you know how to fix the issue

Yes

Are you willing to participate in fixing this issue and create a pull request with the fix

No response

Possible fix

Here is some more context around a fix for this. streamich/react-use#2216

@rtivital
Copy link
Member

I do not understand how providing a default value would solve the mismatch, what if the default value will not match the value on client?

@teaguestockwell
Copy link
Contributor Author

teaguestockwell commented Apr 12, 2022

The default value would work best if it defines the initial state of the client and the server.

After the initial client hydration, it's ok for these to not mach in the following states after the result of the media query is resolved.

@rtivital
Copy link
Member

I still do not get the issue, currently I think that the logic is:

  • App is rendered on server – hook returns false every time
  • App is rendered on client – hook returns true/false based on media query

As far as I know, there is not any middle step where we can insert any additional logic.

@teaguestockwell
Copy link
Contributor Author

Currently there are only the two states that you mentioned.

  • SSR with a false return
  • CSR with a true or false return

React can't correctly hydrate the html generated on the server using fase because the client's virtual dom was generated using the result of the media query: true.

Adding a default value could solve this issue by allowing the first render of the client to match the server for hydration. From there the use effect can set it to the result of the media query.

@rtivital
Copy link
Member

Okay, I got the idea – if default value is provided, it must set value in useEffect

@teaguestockwell
Copy link
Contributor Author

teaguestockwell commented Apr 13, 2022

Yes I believe so. It should be ok to set the initial state using the default value, but the use effect should re set this to the result of the media query after the first render.

The result of the incorrect hydration from what I've seen is broken layouts, but only when the media query initial match is true, so It also may be helpful to throw or warn if typeof window is undefined and no default value is provided.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants