jaredLunde / jaredLunde/react-hook
[useMediaQuery] React hydration doesn't re-evaluate the hook
- Dominant language
- TypeScript
- Stars
- 1.5k
- Forks
- 96
- PR merge metrics
- No merged PRs in 30d
Description
**Describe the bug**
Next.JS does SSR and this hook sends a `false` first and then React doesn't update when it client-side detects a `true`. I made a work-around that makes it work. I am not sure what what internals make this problem occur.
**To Reproduce**
```
const isDesktop = useMediaQuery("(min-width:900px)");
```
I return different HTML depending on whether `isDesktop` is true or false and it seems like React assumes that that the HTML it got from the server was with `isDesktop = true` while it was when `isDesktop = false`. For things like this I have always made a `useEffect` to change the value and not `useState(theCurrentValue)` which would cause a discrepancy between server and browser.
**Expected behavior**
Correctly rendered HTML.
Here is my work-around that makes this work regardless:
```
const isDesktop_ = useMediaQuery("(min-width:900px)");
const [isDesktop, setIsDesktop] = useState(false);
// Work-around for server-side render
useEffect(() => {
setIsDesktop(isDesktop_);
}, [isDesktop_]);
```
Contributor guide
Research direction
Start at the useMediaQuery hook entry point and reproduce the Next.js SSR case with useMediaQuery("(min-width:900px)"). Compare the server-rendered and client-rendered HTML, then verify that the hook re-evaluates and updates the returned value after hydration without requiring the reported useEffect workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100