babel-plugin-styled-components: SSR with styled.extend throws error
minimal example (its with-styled-component next example)
What I do
- yarn run dev
- load page
- reload page
Get error
Warning: React attempted to reuse markup in a container but the checksum was invalid. This generally means that you are using server rendering and the markup generated on the server was not what the client was expecting. React injected new markup to compensate which works but you have lost many of the benefits of server rendering. Instead, figure out why the markup being generated is different on the client or server:
(client) ="1"><div class="sc-bdVaJa iNGvMq" data-
(server) ="1"><div class="sc-jzJRlG fzsTbP" data-
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 18
- Comments: 38 (29 by maintainers)
@evan-scott-zocdoc I actually realised that my workaround would not be performant. So we might have to “scrape” at some v3 ideas and wrap all tagged template input in a wrapper that can be produced by a factory function and carries componentId information around with it.
I’m not sure when I’ll have time to work on this unfortunately
Agreed.
I think since we don’t even agree internally on how to recommend it, it’s a fair assumption that the entire approach is flawed
Also, on this, why is this? I’m kinda of the opposite opinion, that
styled(X)
is better thanX.extends
in almost all cases… 🤷♂️@ckeeney Agreed. I have wasted many hours trying to figure out why I’m getting these errors. There are so many potential issues that can cause the client/server markup mismatch, it would great to update the styled-components docs warning users of this limitation.
Given the issues with SSR and
.extend
, I think a note should be added to the When should I usestyled()
FAQ page. Right now, the answer containsand
I see this FAQ page mentioned a few months ago above, https://github.com/styled-components/babel-plugin-styled-components/issues/79#issuecomment-343401444, but it still hasn’t been changed. Is this no longer the recommended approach?
I use not only
extend
, but alsoextend.attrs()
fairly extensively and I have quite a bit of code that looks like this:Is there any workaround for getting server side rendering working without refactoring all of this to use
styled
and creating wrappers to pass in these additional props?@geelen I do think that the point of extend is to create another component that happens to be a subset of the new one, and like you said:
Which they indeed don’t. I feel like the biggest side effect of introducing
.extend
(and not being clear enough that styled(X) should be avoided as often as possible), indicates to most that this is a pattern that should be commonly used.At the same time the variant suggestion seems really pointless to me. We’ve always tried to promote two patterns here: Inheritance with extend and Composition using mixins. But when I’ve talked to @kof we arrived at an interesting conclusion through a misunderstanding actually.
Since extend doesn’t continue to have a relationship to the parent component, it’s indeed just a composition again, but with an unnecessarily unintuitive, inheritance-like API.
And I think, luckily, we have the solution right here: https://github.com/styled-components/styled-components/issues/1209#issuecomment-334563612 (some of the later composition suggestions are mostly unrelated)
So extend could also be represented as:
So in this case we’d define Parent.styles to be the exact input that was passed to styled.div to create it, i.e. the tagged template literal arguments. This would work no matter how we’d change the actual input for the component.
The huge advantage, imho, is that this makes it way easier to learn styled-components for future users: There’s only one tool of choice and it’s composition through interpolations. Be it with mixins, or the above pattern.
That was easy: when calling
'string'.replace(something, other)
only the first occurrence ofsomething
will be replaced. Will change that toRegExp
with theglobal
flag.