jaredpalmer / after.js

Next.js-like framework for server-rendered React apps built with React Router
https://npm.im/@jaredpalmer/after
MIT License
4.13k stars 201 forks source link

Can't configure after updating to Material Ui v4 #239

Closed mbmohib closed 5 years ago

mbmohib commented 5 years ago

Bug, Feature, or Question?

Question

Current Behavior

Recently I've updated React, Redux, Razzle to the latest version, it's working fine. But after updating to the latest Material UI v4, I can't configure new API with styled-components.

Here is my code

// ./src/Document.js
import React from 'react';
import serialize from 'serialize-javascript';
import { Provider } from 'react-redux';
import { ServerStyleSheet } from 'styled-components';
import { AfterRoot, AfterData } from '@jaredpalmer/after';
import { SheetsRegistry } from 'jss';
import JssProvider from 'react-jss/lib/JssProvider';
import { MuiThemeProvider, createMuiTheme, createGenerateClassName } from '@material-ui/core/styles';
import kajkeyTheme from '../app/theme';

export default class Document extends React.Component {
  static async getInitialProps({ assets, data, renderPage }) {
    const sheet = new ServerStyleSheet();

    const sheetsRegistry = new SheetsRegistry();

    // Create a sheetsManager instance.
    const sheetsManager = new Map();

    // Create a theme instance.
    const theme = createMuiTheme(kajkeyTheme);

    // Create a new class name generator.
    const generateClassName = createGenerateClassName();

    const page = await renderPage(App => props =>
      sheet.collectStyles(
        <JssProvider
          registry={sheetsRegistry}
          generateClassName={generateClassName}
        >
          <MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
            <App {...props} />
          </MuiThemeProvider>
        </JssProvider>
      )
    );
    const styleTags = sheet.getStyleElement();
    const css = sheetsRegistry.toString();

    return { assets, data, ...page, styleTags, css };
  }

  render() {
    const { helmet, assets, data, styleTags, css, serverState } = this.props;
    // get attributes from React Helmet
    const htmlAttrs = helmet.htmlAttributes.toComponent();
    const bodyAttrs = helmet.bodyAttributes.toComponent();

    return (
      <html {...htmlAttrs}>
        <head>
          <meta httpEquiv="X-UA-Compatible" content="IE=edge" />
          <meta charSet="utf-8" />
          <title>
            TITLE
          </title>
          <meta name="viewport" content="width=device-width, initial-scale=1" />
          {helmet.title.toComponent()}
          {helmet.meta.toComponent()}
          {helmet.link.toComponent()}
          <link
            href="https://fonts.googleapis.com/css?family=Noto+Sans"
            rel="stylesheet"
          />
          <link
            href="https://fonts.googleapis.com/earlyaccess/notosansbengali.css"
            rel="stylesheet"
          />
          <script src="https://apis.google.com/js/platform.js" async defer />
          {styleTags}
          {assets.client.css && (
            <link rel="stylesheet" href={assets.client.css} />
          )}
          <style type="text/css" id="jss-server-side">
            {css}
          </style>
        </head>
        <body {...bodyAttrs}>
          <AfterRoot />
          <AfterData data={data} />
          <script
            type="text/javascript"
            src={assets.client.js}
            defer
            crossOrigin="anonymous"
          />
          <span
            dangerouslySetInnerHTML={
              { __html: `<script>window.__PRELOADED_STATE__ = ${serialize(serverState)}</script>` } // prettier-ignore
            }
          />
        </body>
      </html>
    );
  }
}
// ./src/Client.js
import React from 'react';
import { hydrate } from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { ensureReady, After } from '@jaredpalmer/after';
import JssProvider from 'react-jss/lib/JssProvider';
import {
  createMuiTheme,
  MuiThemeProvider,
  createGenerateClassName,
} from '@material-ui/core/styles';
import { ThemeProvider } from 'styled-components';
import kajkeyTheme from '../app/theme';
import GlobalStyle from '../app/styles/global-styles';
import routes from '../app/routes/index';
import { CommonHeaderLayout } from '../app/views/layouts';
import configureStore from '../app/state/store';
import ReactGA from 'react-ga';

// Init Google Analytics
ReactGA.initialize('UA-65383714-3');

const theme = createMuiTheme(kajkeyTheme);
const generateClassName = createGenerateClassName();
const store = configureStore(window.__PRELOADED_STATE__);

ensureReady(routes).then(data =>
  hydrate(
    <Provider store={store}>
      <JssProvider generateClassName={generateClassName}>
        <MuiThemeProvider theme={theme}>
          <ThemeProvider theme={kajkeyTheme}>
            <BrowserRouter>
              <CommonHeaderLayout>
                <GlobalStyle />
                <After data={data} routes={routes} />
              </CommonHeaderLayout>
            </BrowserRouter>
          </ThemeProvider>
        </MuiThemeProvider>
      </JssProvider>
    </Provider>,
    document.getElementById('root')
  )
);

if (module.hot) {
  module.hot.accept();
}

Deepesh316 commented 4 years ago

Is this fixed? If yes please comment here on how you fixed, will be useful for others who are facing the same issue.

nimaa77 commented 4 years ago

@Deepesh316 we have an example for material-ui and redux check it out at here https://github.com/jaredpalmer/after.js/tree/master/examples/with-material-ui https://github.com/jaredpalmer/after.js/tree/master/examples/with-redux

if you want I can create a with-redux-and-material-ui example as well