Render different component for ssr mode and client side
peppescg opened this issue · comments
Hi, I have a strange behavior. I want render a component in server side mode using user agent, but in client I want use media query, beacuse it is possible that bowser client is resized on a mobile width.
With js disabled it works well, but if it is enabled I have a warning in console
{ userAgent.desktop ?
(
<Media query="(min-width: 768px)" >
{matches =>
matches ? (
<div>Desktop <LmProductDesktop data={data}/></div>
) : (
<div>Mobile <LmProductMobile data={data}/></div>
)
}
</Media>
) :
(
<Media query="(max-width: 767px)" >
{matches =>
matches ? (
<div>Mobile <LmProductMobile data={data}/></div>
) : (
<div>Desktop <LmProductDesktop data={data}/></div>
)
}
</Media>
)
}
Now I am in desktop mode, so I rendered ssr desktop component, in the client with browser resized, I have the warning, in the dom elments I saw the correct css of mobile component, but the desktop component wrapped into media tag, the media mathched is setted to false and if I set true I saw the desktop component not the mobile.
Warning: Text content did not match. Server: "Desktop " Client: "Mobile "
Any ideas?
@peppescg I suggest you use the defaultMatches
prop:
<Media query="(min-width: 768px)" defaultMatches={userAgent.desktop}>
{matches =>
matches ? (
<div>Desktop <LmProductDesktop data={data}/></div>
) : (
<div>Mobile <LmProductMobile data={data}/></div>
)
}
</Media>
With js disabled it works well, but if it is enabled I have a warning in console
I assume the warning you're getting is coming from React, warning you that there is a mismatch between the server-rendered markup and the initial client-side render. It is impossible to prevent the mismatch from ever occurring, since at SSR-time we cannot know with 100% certainty whether the media queries will match on the client. As you point out, you can have a "desktop" user agent, but have your browser window resized, such that it will match your "mobile" media query.
For what it's worth, we are discussing a two-pass rendering setup in #81, which should prevent the warnings from showing up.