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

React 16: Mismatched HTML Warning logged when hydrating Portals rendered to document.head #11169

Closed
tizmagik opened this issue Oct 10, 2017 · 3 comments

Comments

@tizmagik
Copy link

tizmagik commented Oct 10, 2017

Do you want to request a feature or report a bug?

Bug?

What is the current behavior?

Rendering a portal to document.head on the server causes React to log a Warning on unexpected markup while hydrating server markup. Currently this happens when using react-head

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar (template for React 16: https://jsfiddle.net/Luktwrdm/, template for React 15: https://jsfiddle.net/hmbg7e9w/).

I'm not sure if it's possible to simulate this in jsfiddle, since it requires server-rendering and access to document.head, but a fairly minimal repro case is in react-head's example app, which you can clone and run via doing the following:

git clone git@github.com:tizmagik/react-head.git
cd react-head
npm install
npm run dev
open http://localhost:3000

You'll then see the React warning logged.

If you have thoughts on a simpler way to repro this, happy to do that as well!

What is the expected behavior?

It's entirely possible that this is just a usage of React Portals that wasn't anticipated, but i'm not sure if this is an invalid use case? Would like to get your thoughts and if there's a better approach than what I'm currently doing with react-head?

Besides the warning, the module/app seems to function exactly as expected.

At a high level, this is how react-head works:

During server-rendering <head /> tags (e.g. <meta /> etc) are collected in an array, which are renderToString()d and placed in the server template <head />, then on the client, these server-rendered tags are querySelected and removed, to be replaced by ReactDOM.createPortal() in order to support SPA functionality from then on.

Here's the issue in react-head: tizmagik/react-head#1

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

React 16

@tizmagik
Copy link
Author

Also, just wanted to say awesome work with React 16! Really excited to make use of portals a bit more and for what's ahead! 🎉

@gaearon
Copy link
Collaborator

gaearon commented Oct 10, 2017

Instead of reading canUseDOM, can you put it into state? Initially it would be false to match the server. But in componentDidMount you can setState({canUseDOM: true}). This will trigger a re-render after hydration so it shouldn’t produce a warning.

@tizmagik
Copy link
Author

Ah, of course! That's what I get for not following my own advice about avoiding canUseDOM. Thanks @gaearon 🙏 Working now with this PR: tizmagik/react-head#9

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

No branches or pull requests

2 participants