【问题标题】:How to manage Server side rendering, in Meteor environment with React, Material UI and Styled-components?如何在 Meteor 环境中使用 React、Material UI 和 Styled-components 管理服务器端渲染?
【发布时间】:2023-03-24 22:05:01
【问题描述】:

我已按照Meteor docs 中的说明实施。我添加的所有组件 css 都会被渲染。但是 Material UI 组件的外观和感觉不像我在客户端版本中的那样。

我已经尝试过这个MaterialUI Docs,但还没有运气。另外我没有使用react-jss

如果有人知道任何我可以使用的示例项目,那就太好了。

【问题讨论】:

    标签: reactjs meteor material-ui styled-components server-side-rendering


    【解决方案1】:

    这个问题的答案很简单,只要按照material ui & styled-components docs中的文档,使用两个SSR主题中实现的功能即可。

    然后你有来自 Material ui 和 styled-components 的样式标签工作正常。 我在这里展示了我的 SSR 代码,它遵循如何在流星环境中进行 SSR 渲染。

    SSR 实施文档:

    Meteor docs with styled-components usage

    MaterialUI docs

    import React from 'react'
    import { MuiThemeProvider, createMuiTheme, createGenerateClassName } from '@material-ui/core/styles'
    import { SheetsRegistry } from 'react-jss/lib/jss'
    import JssProvider from 'react-jss/lib/JssProvider'
    import { renderToString } from 'react-dom/server'
    import { onPageLoad } from 'meteor/server-render'
    import { StaticRouter } from 'react-router'
    import { Provider } from 'react-redux'
    import { Helmet } from 'react-helmet'
    import { ServerStyleSheet } from 'styled-components'
    import MainApp from '../imports/app/MainApp'
    import store from '../imports/app/store/store'
    
    onPageLoad(sink => {
      const context = {}
      // Create a sheetsRegistry instance.
      const sheetsRegistry = new SheetsRegistry()
    
      // Create a sheetsManager instance.
      const sheetsManager = new Map()
      // Theme Font Change
      const theme = createMuiTheme({
        typography: {
          fontFamily: 'FuturaPT-Light',
          fontWeight: 'normal',
          fontStyle: 'normal',
        },
      })
      const generateClassName = createGenerateClassName()
      const sheet = new ServerStyleSheet()
    
      const App = () => (
        <Provider store={store}>
          <StaticRouter location={sink.request.url} context={context}>
            <JssProvider registry={sheetsRegistry} generateClassName={generateClassName}>
              <MuiThemeProvider theme={theme} sheetsManager={sheetsManager}>
                <MainApp />
              </MuiThemeProvider>
            </JssProvider>
          </StaticRouter>
        </Provider>
      )
    
      sheet.collectStyles(<App />)
      sink.renderIntoElementById('react-root', renderToString(<App />))
      const css = sheetsRegistry.toString()
      const helmet = Helmet.renderStatic()
      sink.appendToHead(helmet.meta.toString())
      sink.appendToHead(helmet.title.toString())
      sink.appendToHead(`<style id="jss-server-side">${css}</style>`) // material-ui css attached
      sink.appendToHead(sheet.getStyleTags()) // styled-components css attached
    
      // console.log(html)
      const preloadedState = store.getState()
    
      sink.appendToBody(
        `<div id="pre-loaded-state" style="display:none">${JSON.stringify(preloadedState).replace(
          /</g,
          '\\u003c'
        )}</div>`
      )
    })
    

    【讨论】:

      【解决方案2】:

      您可以尝试使用 npm 包 maka-cli,并使用 react、material-ui 和 SSR 生成样板应用程序,看看我是如何做到的:

      $ maka create NewApp --theme=material --ssr=true --client=react

      然后,导航到文件:

      ./NewApp/imports/startup/server/index.jsx

      您可以看到应用程序如何使用 SSR 搭建材料 UI。请注意,这不是使用最新的 material-ui (1.0.0-beta.36) ...但这可能是一个开始!

      /************* SSR Code ********************/
      import Routes from '../lib/routes.jsx';
      import React from 'react';
      import { renderToStaticMarkup } from 'react-dom/server';
      import { onPageLoad } from 'meteor/server-render';
      import { StaticRouter } from 'react-router-dom';
      import { createMemoryHistory } from 'history';
      
      
      import { SheetsRegistry } from 'react-jss/lib/jss';
      import JssProvider from 'react-jss/lib/JssProvider';
      import { create } from 'jss';
      import preset from 'jss-preset-default';
      import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
      import createGenerateClassName from 'material-ui/styles/createGenerateClassName';
      import { grey } from 'material-ui/colors';
      
      onPageLoad(sink => {
          const history = createMemoryHistory(sink.request.url.pathname);
          const App = (props) => (
              <StaticRouter
                  location={props.location}
                  context={{}}>
                  <Routes history={history}/>
              </StaticRouter>
          );
          // Create a sheetsRegistry instance.
          const sheetsRegistry = new SheetsRegistry();
      
          // Create a theme instance.
          const theme = createMuiTheme({
              palette: {
                  primary: grey,
                  accent: grey,
                  type: 'light',
              },
          });
      
          const jss = create(preset());
          jss.options.createGenerateClassName = createGenerateClassName;
      
          const html = renderToStaticMarkup(
            <JssProvider registry={sheetsRegistry} jss={jss}>
              <MuiThemeProvider theme={theme} sheetsManager={new Map()}>
                <App location={sink.request.url} />
              </MuiThemeProvider>
            </JssProvider>
          );
          const css = sheetsRegistry.toString();
          sink.appendToHead(`<style id="jss-server-side">${css}</style>`);
          sink.renderIntoElementById('app', html);
      });
      

      【讨论】:

      • 感谢您的努力,但我的问题是如何让它在流星环境中一起使用材料 ui 和样式组件。
      【解决方案3】:

      即使他们使用 Bootstrap 而不是 Material UI,我还是建议您查看这个管理 SSR 的样板:cleverbeagle pup,它现在也使用 Styled-components。它将让您很好地了解如何实现它,或者您可以尝试将 css 框架和组件迁移到 Material UI。

      【讨论】:

      • 感谢您的努力,但这并不能解决我的问题。我试过了,它只显示了带有样式组件的 SSR 实现
      猜你喜欢
      • 2020-10-01
      • 2018-05-18
      • 2021-10-30
      • 2019-02-24
      • 2019-06-03
      • 2018-07-29
      • 2020-01-18
      • 2020-05-14
      • 1970-01-01
      相关资源
      最近更新 更多