Closed
Description
styled-jsx
is awesome but it handles style generation during SSR in a very unsafe way. It uses side effects that can lead to style collision when user will try to render something async (say hello to renderToStream
and react@17
in future).
So I want to propose a better solution to this problem.
Instead of using flush
from styled-jsx/server
and internal stylesheet singleton we need to be able to provide custom styleSheetRegistry
to controlled virtual tree.
This can be done with react.js context.
// server.js
import { StyleSheetRegistryProvider, StyleSheetRegistry } from 'styled-jsx/server';
const registry = new StyleSheetRegistry();
const app = ReactDOM.renderToString((
<StyleSheetRegistryProvider registry={registry}>
<App />
</StyleSheetRegistryProvider>
));
const styles = registry.toHTML(); // or .toComponents()
const html = `
<!doctype html>
<html>
<head>${styles}</head>
<body>
<div id="root">${app}</div>
</body>
</html>
`;
More details:
- If no registry is provided to
StyleSheetRegistryProvider
then the default one will be used. This can be useful on the client side. - If no
StyleSheetRegistryProvider
is provided then<style jsx />
must be noop. This will be useful when you need to do something that is not related to rendering markup. Something like data resolution for the final render when you don't want to do extra work that you don't need. StyleSheetRegistryProvider
can be combined but children provider should not share its styles with a parent provider.StyleSheetRegistryProvider
can be used as config for handled styles.
@giuseppeg what do you think?