Description
Thanks for this great library!
I recently had an issue while rehydrating server side rendered markup that contained a react-media component. I'm pretty sure it was because the server side rendered markup was the desktop version and on the client the component immediately rendered the mobile markup when the respective media query matches.
With React 16 it's no longer mandatory to have a 100% matching markup when rehydrating; React will try to patch the DOM as best as it can. In practice this can lead to some problems though if the DOM is really different – resulting in an incosistent DOM that is a mix of the desktop and the mobile markup.
The React docs suggest a two-pass render for such scenarios that will avoid the problem:
If you intentionally need to render something different on the server and the client, you can do a two-pass rendering. Components that render something different on the client can read a state variable like this.state.isClient, which you can set to true in componentDidMount(). This way the initial render pass will render the same content as the server, avoiding mismatches, but an additional pass will happen synchronously right after hydration. Note that this approach will make your components slower because they have to render twice, so use it with caution.
Maybe it could be helpful to move calling this.updateMatches()
from cWM to cDM. This is a disadvantage for clientside-only apps though, as it could add a potentially unnecessary render.
One strategy could be to remove the default for the defaultMatches
prop. As this property is only needed for server side rendering, we could invoke the two-phase render only when this prop is actively provided by the user.
What do you think?