[question] Is it possible to generate consistent classNames despite the order of rendering?
See original GitHub issueIn my project I have an issue with react and SSR. ReactDOM.hydrate
updates only text content of the DOM element, but not attributes, so if classNames are different on client side, react will not change it.
For example, if JSS on server generates classname MyComponent-key-0-2-10
, server return this HTML:
<style>.MyComponent-key-0-2-10 {...}</style>
<div class="MyComponent-key-0-2-10" />
Then on client side JSS generates MyComponent-key-0-2-25
and adds styles to the <HEAD>
:
<style>.MyComponent-key-0-2-25 {...}</style>
But react is not changing <div class="MyComponent-key-0-2-10" />
to <div class="MyComponent-key-0-2-25" />
on initial render. As I found out this behaviour was made intentional to force react to reuse as much as possible from server side render.
It seems that I have different classNames because some components are rendered on client side only, so the counter is inconsistent between server and client. But my app is pretty huge and it is nearly impossible to find which component was rendered just on client side. So I thought if it’s possible to generate unique classNames based on styles object, maybe using hash function instead of counter (performance issues are out of the scope atm). If it’s possible, we’ll get the same classNames despite the order of rendering. My goal is to have className like componentName-key-hash
.
I tried to use createGenerateClassName
function, but it’s calling before plugins execution, so the rule object is not filled with styles yet. Then I tried to add custom plugin at the end of the queue and calculate hash in onProcessStyle
callback, but the rule is already have className at this point, and probably it’s a bad idea to mutate rule and sheet objects here.
So, my question is, can we generate classNames this way? Is it even possible?
Issue Analytics
- State:
- Created 5 years ago
- Comments:10 (8 by maintainers)
Top GitHub Comments
@bungu Even if you solve the class name issue, you should still have a problem, it’s the tips of the iceberg. If you are rendering a component on the client and not on the server, it won’t work properly. You should be able to quickly find the culprit with dichotomy, no matter how big your app is. Also, have a look at https://material-ui.com/utils/no-ssr/. It should solve your problem.
Rehydration should be the same, but then one could render anything else.