The default class names (.jss123) created by jss will be merged from different dynamic imports which breaks the design.
Setup:
Solution:
replace default name generator (http://cssinjs.org/js-api/?v=v9.5.0#generate-your-own-class-names) with a variation which uses random strings as part of the class name and wrap your app with this HOC.
import React, { Component } from 'react';
import JssProvider from 'react-jss/lib/JssProvider';
import { create } from 'jss';
import preset from 'jss-preset-default';
//import createGenerateClassName from 'material-ui/styles/createGenerateClassName';
import Layout from './components/pages/layout';
const createGenerateClassName = () => {
let counter = 0
return (rule, sheet) => `c${Math.random().toString(36).substring(2, 4) + Math.random().toString(36).substring(2, 4)}-${rule.key}-${counter++}`
}
const jss = create(preset());
// Custom Material-UI class name generator for better debug and performance.
jss.options.createGenerateClassName = createGenerateClassName;
function App() {
return (
<JssProvider jss={jss}>
<Layout />
</JssProvider>
);
}
export default App;
please add this to the recipe section of your docs
I do not fully understand problem. I will need to investigate. Thanks for the tip
Yes I was able to reproduce. Strange thing. I wonder how JSS works with SSR.
UPD: oh my
Once JS on the client is loaded, components initialized and your JSS styles are regenerated, it's a good time to remove server-side generated style tag in order to avoid side-effects
render(<Button />, document.getElementById('app'), () => {
// We don't need the static css any more once we have launched our application.
const ssStyles = document.getElementById('server-side-styles')
ssStyles.parentNode.removeChild(ssStyles)
})
basically JSS doesn't support rehydration
import React from 'react';
import { hydrate, render } from 'react-dom';
import { loadComponents } from 'loadable-components';
import { getState } from 'loadable-components/snap';
import Index from './pages/index';
const app = <Index />;
const rootElement = document.getElementById('root');
loadComponents().then(() => {
render(app, rootElement, () => {
Array.from(document.querySelectorAll('[data-jss-snap]')).forEach(elem =>
elem.parentNode.removeChild(elem),
);
});
});
window.snapSaveState = () => {
Array.from(document.querySelectorAll('[data-jss]')).forEach(elem =>
elem.setAttribute('data-jss-snap', ''),
);
return getState();
};
Thank you @aheissenberger
function App() {
perfect, this solution was amazing , thanks a lot
thanks @aheissenberger and @stereobooster! Very helpful!
@aheissenberger I had today same problem with React.lazy() and JSS from Material-UI, without SSR. Your solution seems to be helpful. Do you think it is 1 to 1 related? I think so, but I'm not 100% sure.
Another solution
const generateClassName = createGenerateClassName({
productionPrefix: navigator.userAgent === 'ReactSnap' ? 'snap' : 'jss',
});
<StylesProvider jss={jss} generateClassName={generateClassName}>
<Layout/>
</StylesProvider>
Most helpful comment
Yes I was able to reproduce. Strange thing. I wonder how JSS works with SSR.
UPD: oh my
Another fix
basically JSS doesn't support rehydration