ctrlplusb / react-async-bootstrapper

Execute a bootstrap method on your React/Preact components. Useful for data prefetching and other activities.
MIT License
117 stars 12 forks source link

in material-ui v1.0 has some wrong #10

Closed cooliean closed 6 years ago

cooliean commented 6 years ago
const serialize = require("serialize-javascript");
const ejs = require('ejs');

const ReactDOMServer = require("react-dom/server");
const bootstrapper = require('react-async-bootstrapper')
const Helmet = require('react-helmet').default
const SheetsRegistry = require('react-jss').SheetsRegistry
const createGenerateClassName = require('@material-ui/core/styles').createGenerateClassName
const createMuiTheme = require('@material-ui/core/styles').createMuiTheme
const themeColors = require('../../client/themes/theme-default')

const getStoreState = (stores) => {
  return Object.keys(stores).reduce((result, storeName) => {
    result[storeName] = stores[storeName].toJson()
    return result;
  }, {})
}

module.exports = (bundle, template, req, res) => {
  const user = req.session.user;
  const createStoreMap = bundle.createStoreMap
  const createApp = bundle.default
  const routerContext = {};
  const stores = createStoreMap();
  const sheetsRegistry = new SheetsRegistry();
  // Create a theme instance.
  const theme = createMuiTheme(themeColors);
  const generateClassName = createGenerateClassName();

  if (user) {
    stores.appState.user.isLogin = true;
    stores.appState.user.info = user;
  }

  const app = createApp(stores, routerContext, sheetsRegistry, generateClassName, theme, req.url);
  return new Promise((resolve, reject) => {
    bootstrapper(app).then(() => {
      console.log('==json==================');
      console.log(JSON.stringify(routerContext, null, '\t'));
      console.log('========================');
      if (routerContext.url) {
        res.status(302).setHeader('Location', routerContext.url)
        res.end()
        return
      }
      const helmet = Helmet.rewind();
      const state = getStoreState(stores);
      const content = ReactDOMServer.renderToString(app);
      const html = ejs.render(template, {
        appString: content,
        initialState: serialize(state),
        meta: helmet.meta.toString(),
        title: helmet.title.toString(),
        style: helmet.style.toString(),
        link: helmet.link.toString(),
        materialCss: sheetsRegistry.toString(),
      })
      res.send(html);
      resolve()
    }).catch(reject)
  })
}

it will be rerender