React warning: Prop `className` did not match.
See original GitHub issueCurrent behavior:
When using SSR and in dev mode, the classname generated on the server doesn’t match what’s on the client.
I think I’ve narrowed it down to an issue involving sourcemaps.
In https://github.com/emotion-js/emotion/blob/117c6e42687cdcb773153f7400c5a430f228aa73/packages/serialize/src/index.js#L387 it seems the code is attempting to extract the sourcemap string in the style:
if (process.env.NODE_ENV !== 'production') {
styles = styles.replace(sourceMapPattern, match => {
sourceMap = match
return ''
})
}
The particular elements that gives rise to this bug seem to have multiple sourcemaps. This is the style before the replace
(I’ve abbreviated the base64 string itself):
color: #1a1a1a;
font-weight: bold;
margin: 0;
padding: 0;
color:;font-size:32px;line-height:1.15;margin-bottom:4px;/*# sourceMappingURL=data:application/json;charset=utf-8;base64,ey...19 */label:ColoredCardHeading;color:#BB2F89;hyphens:auto;/*# sourceMappingURL=data:application/json;charset=utf-8;base64,ey...19 */
And this is the style after replace:
color: #1a1a1a;
font-weight: bold;
margin: 0;
padding: 0;
color:;font-size:32px;line-height:1.15;margin-bottom:4px;label:ColoredCardHeading;color:#BB2F89;hyphens:auto;/*# sourceMappingURL=data:application/json;charset=utf-8;base64,ey...19
This particular component is created by extending another component in another file:
(file1.js)
import Component2 from "file2.js";
const Component1 = styled(Component2).`...`
(file2.js)
const Component3 = ...
const Component2 = styled(Component3)`...`
export default Component2
The base64 encoded strings in the styles above point to file1
and file2
respectively. So I suspect either there is a bug in sourcemap generation which creates two instances of sourcemap in the same style string, or a problem with the replace mechanism that extracts one and not the other.
The actual mismatch happens because the server generated sourcemap has "sources": ["file1.js"]
in the base64 encoded json sourcemap, while on the client this is fully qualified: "sources": ["/Users/.../file1.js"]
To reproduce:
I’d be happy to create a repo to demo this, it will take me some time though due to SSR and the use of extractCritical
.
Expected behavior:
Using the basic apis for styled
should not create mismatched classname on client & server.
Environment information:
react
version: 16.6.0@emotion
version: 10.0.27
Issue Analytics
- State:
- Created 4 years ago
- Comments:12 (6 by maintainers)
Top GitHub Comments
@Andarist It still persist for Firefox and Safari, in chrome works fine.
@fsaheli funny thing - this most likely got fixed by accident on the
next
branch. The goal of the change was to give more accurate source maps to the browser for composed styles and to make this happen we had to addg
flag to thatsourceMapPattern
: https://github.com/emotion-js/emotion/blob/d950d7d3a2d0a4c77d9037c0dbeae9d0b24e6577/packages/serialize/src/index.js#L335I believe this accidentally fixed your problem. I encourage you to migrate to v11 (available on npm) anyway, even if you have already worked around your problem.