Skip to content

Commit

Permalink
[SSR] Remove the singleton hack ✨ (mui#7965)
Browse files Browse the repository at this point in the history
  • Loading branch information
oliviertassinari authored Aug 31, 2017
1 parent d208387 commit 0058200
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 69 deletions.
29 changes: 9 additions & 20 deletions docs/src/modules/components/AppWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@

import React from 'react';
import PropTypes from 'prop-types';
import { JssProvider } from 'react-jss';
import { getContext } from 'docs/src/modules/styles/context';
import getContext, { getTheme } from 'docs/src/modules/styles/getContext';
import { connect } from 'react-redux';
import AppFrame from 'docs/src/modules/components/AppFrame';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import blue from 'material-ui/colors/blue';
import pink from 'material-ui/colors/pink';
import { MuiThemeProvider } from 'material-ui/styles';
import { lightTheme, darkTheme, setPrismTheme } from 'docs/src/modules/utils/prism';

// Injected the insertion-point-jss after docssearch
Expand Down Expand Up @@ -44,13 +41,7 @@ class AppWrapper extends React.Component<any, any> {

componentWillReceiveProps(nextProps) {
if (nextProps.dark !== this.props.dark) {
this.styleContext.theme = createMuiTheme({
palette: {
primary: blue,
secondary: pink,
type: nextProps.dark ? 'dark' : 'light',
},
});
this.styleContext.theme = getTheme(nextProps.dark);

if (nextProps.dark) {
setPrismTheme(darkTheme);
Expand All @@ -66,14 +57,12 @@ class AppWrapper extends React.Component<any, any> {
const { children } = this.props;

return (
<JssProvider registry={this.styleContext.sheetsRegistry} jss={this.styleContext.jss}>
<MuiThemeProvider
theme={this.styleContext.theme}
sheetsManager={this.styleContext.sheetsManager}
>
<AppFrame>{children}</AppFrame>
</MuiThemeProvider>
</JssProvider>
<MuiThemeProvider
theme={this.styleContext.theme}
sheetsManager={this.styleContext.sheetsManager}
>
<AppFrame>{children}</AppFrame>
</MuiThemeProvider>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,11 @@ function createContext() {
};
}

export function setContext() {
// Singleton hack as there is no way to pass variables from _document.js to pages yet.
global.__INIT_MATERIAL_UI__ = createContext();
}

export function getContext() {
export default function getContext() {
// Make sure to create a new store for every server-side request so that data
// isn't shared between connections (which would be bad)
if (!process.browser) {
return global.__INIT_MATERIAL_UI__;
return createContext();
}

// Reuse context on the client-side
Expand Down
31 changes: 10 additions & 21 deletions examples/nextjs/components/withRoot.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
/* eslint-disable flowtype/require-valid-file-annotation */

import React, { Component } from 'react';
import { JssProvider } from 'react-jss';
import { withStyles, MuiThemeProvider } from 'material-ui/styles';
import wrapDisplayName from 'recompose/wrapDisplayName';
import { getContext } from '../styles/context';
import getContext from '../styles/getContext';

// Apply some reset
const styles = theme => ({
Expand Down Expand Up @@ -34,6 +33,10 @@ function withRoot(BaseComponent) {
return {};
}

componentWillMount() {
this.styleContext = getContext();
}

componentDidMount() {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
Expand All @@ -43,26 +46,12 @@ function withRoot(BaseComponent) {
}

render() {
const context = getContext();

if (process.browser) {
return (
<MuiThemeProvider theme={context.theme}>
<AppWrapper>
<BaseComponent {...this.props} />
</AppWrapper>
</MuiThemeProvider>
);
}

return (
<JssProvider registry={context.sheetsRegistry} jss={context.jss}>
<MuiThemeProvider theme={context.theme} sheetsManager={context.sheetsManager}>
<AppWrapper>
<BaseComponent {...this.props} />
</AppWrapper>
</MuiThemeProvider>
</JssProvider>
<MuiThemeProvider theme={this.styleContext.theme}>
<AppWrapper>
<BaseComponent {...this.props} />
</AppWrapper>
</MuiThemeProvider>
);
}
}
Expand Down
18 changes: 11 additions & 7 deletions examples/nextjs/pages/_document.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

import React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
import { getContext, setContext } from '../styles/context';
import { JssProvider } from 'react-jss';
import getContext from '../styles/getContext';

class MyDocument extends Document {
render() {
const context = getContext();
return (
<html lang="en" dir="ltr">
<Head>
Expand All @@ -26,7 +26,7 @@ class MyDocument extends Document {
*/}
<link rel="manifest" href="/static/manifest.json" />
{/* PWA primary color */}
<meta name="theme-color" content={context.theme.palette.primary[500]} />
<meta name="theme-color" content={this.props.stylesContext.theme.palette.primary[500]} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
Expand Down Expand Up @@ -59,13 +59,17 @@ MyDocument.getInitialProps = ctx => {
// 1. page.getInitialProps
// 3. page.render

// Reset the context for handling a new request.
setContext();
const page = ctx.renderPage();
// Get the context with the collected side effects.
// Get the context to collected side effects.
const context = getContext();
const page = ctx.renderPage(Component => props => (
<JssProvider registry={context.sheetsRegistry} jss={context.jss}>
<Component {...props} />
</JssProvider>
));

return {
...page,
stylesContext: context,
styles: (
<style
id="jss-server-side"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,11 @@ function createContext() {
};
}

export function setContext() {
// Singleton hack as there is no way to pass variables from _document.js to pages yet.
global.__INIT_MATERIAL_UI__ = createContext();
}

export function getContext() {
export default function getContext() {
// Make sure to create a new store for every server-side request so that data
// isn't shared between connections (which would be bad)
if (!process.browser) {
return global.__INIT_MATERIAL_UI__;
return createContext();
}

// Reuse context on the client-side
Expand Down
17 changes: 10 additions & 7 deletions pages/_document.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

import React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
import { getContext, setContext } from 'docs/src/modules/styles/context';
import getContext from 'docs/src/modules/styles/getContext';
import { JssProvider } from 'react-jss';
import CleanCSS from 'clean-css';

const cleanCSS = new CleanCSS();

class MyDocument extends Document {
render() {
const context = getContext();
return (
<html lang="en" dir="ltr">
<Head>
Expand All @@ -33,7 +33,7 @@ class MyDocument extends Document {
*/}
<link rel="manifest" href="/static/manifest.json" />
{/* PWA primary color */}
<meta name="theme-color" content={context.theme.palette.primary[500]} />
<meta name="theme-color" content={this.props.stylesContext.theme.palette.primary[500]} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500"
Expand Down Expand Up @@ -78,11 +78,13 @@ MyDocument.getInitialProps = ctx => {
// 1. page.getInitialProps
// 3. page.render

// Reset the context for handling a new request.
setContext();
const page = ctx.renderPage();
// Get the context with the collected side effects.
// Get the context to collected side effects.
const context = getContext();
const page = ctx.renderPage(Component => props => (
<JssProvider registry={context.sheetsRegistry} jss={context.jss}>
<Component {...props} />
</JssProvider>
));

let css = context.sheetsRegistry.toString();
if (process.env.NODE_ENV === 'production') {
Expand All @@ -91,6 +93,7 @@ MyDocument.getInitialProps = ctx => {

return {
...page,
stylesContext: context,
styles: (
<style
id="jss-server-side"
Expand Down

0 comments on commit 0058200

Please sign in to comment.