首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Material UI:页面初始加载时闪烁(Razzle)

Material UI:页面初始加载时闪烁(Razzle)
EN

Stack Overflow用户
提问于 2020-10-23 15:00:15
回答 1查看 925关注 0票数 10

我已经在我的服务器端渲染应用程序中集成了材料UI,并遵循了给定的here代码。Material UI css被添加到服务器端本身的html中。

但是,在初始加载时,不会应用材质ui样式,这会导致其闪烁。

我尝试使用<cssbaseline>和下面的代码,但没有看到任何区别。

下面是我的代码: server.js

代码语言:javascript
复制
import App from '../common/containers/App';
import { Provider } from 'react-redux';
import React from 'react';
import configureStore from '../common/store/configureStore';
import express from 'express';
import qs from 'qs';
import { renderToString } from 'react-dom/server';
import serialize from 'serialize-javascript';
import { StaticRouter, matchPath } from 'react-router-dom';
import {theme} from '../theme';
import { ServerStyleSheets, ThemeProvider } from '@material-ui/styles';
import routes from './routes'
import "../common/assets/SCSS/app.scss";

const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
const server = express();
server
  .disable('x-powered-by')
  .use(express.static(process.env.RAZZLE_PUBLIC_DIR))
  .get('/*', (req, res) => {
    const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
    const promise = activeRoute.fetchInitialData
      ? activeRoute.fetchInitialData(req.path)
      : Promise.resolve()
    promise.then((apiResult) => {
      const sheets = new ServerStyleSheets();
      const counter =  apiResult || 0;
      const preloadedState = { counter };
      const store = configureStore(preloadedState);
      const context = {};
      const markup = renderToString(
         sheets.collect(
           <Provider store={store}>
            <ThemeProvider theme={theme}>
              <StaticRouter location={req.url} context={context}>
                <App />
              </StaticRouter>
            </ThemeProvider>
          </Provider>
      ));
   const css = sheets.toString();
      const finalState = store.getState();
      const html = `<!doctype html>
          <html lang="">
          <head>
              ${assets.client.css
                ? `<link rel="stylesheet" href="${assets.client.css}">`
                : ''}
                ${css ? `<style id='jss-ssr'>${css}</style>` : ''}
                ${process.env.NODE_ENV === 'production'
                  ? `<script src="${assets.client.js}" defer></script>`
                  : `<script src="${assets.client.js}" defer crossorigin></script>`}
          </head>
          <body>
              <div id="root">${markup}</div>
              <script>
                window.__PRELOADED_STATE__ = ${serialize(finalState)}
              </script>
          </body>
      </html>`
 res.send(html);
    });
  });

export default server;

Client.js

代码语言:javascript
复制
import React,{useEffect} from 'react';
import { hydrate } from 'react-dom';
import {theme} from '../theme';
import { ThemeProvider } from '@material-ui/styles';
import { Provider } from 'react-redux';
import configureStore from '../common/store/configureStore';
import App from '../common/containers/App';
import { BrowserRouter } from "react-router-dom";
import "../common/assets/SCSS/app.scss";
import * as serviceWorker from '../serviceWorker';
import CssBaseline from '@material-ui/core/CssBaseline';

const store = configureStore(window.__PRELOADED_STATE__);
const Client = () => {
  useEffect(() => {
   
    const jssStyles = document.querySelector('#jss-ssr');
    if (jssStyles) {
      jssStyles.parentElement.removeChild(jssStyles);
    }
  }, []);

  return(
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </ThemeProvider>
    </Provider>
  );

}


hydrate(<Client />,document.getElementById('root'));
EN

回答 1

Stack Overflow用户

发布于 2020-10-27 10:02:19

这是因为您的客户端代码在生成客户端样式之前删除了服务器生成的样式。

react-dom提供的hydrate函数有一个第三个参数,这是一个回调函数,在应用程序水合完成后调用。

此回调函数应用于确保应用程序已完成水合,并已生成客户端样式。

代码语言:javascript
复制
import React,{useEffect} from 'react';
import { hydrate } from 'react-dom';
import {theme} from '../theme';
import { ThemeProvider } from '@material-ui/styles';
import { Provider } from 'react-redux';
import configureStore from '../common/store/configureStore';
import App from '../common/containers/App';
import { BrowserRouter } from "react-router-dom";
import "../common/assets/SCSS/app.scss";
import * as serviceWorker from '../serviceWorker';
import CssBaseline from '@material-ui/core/CssBaseline';

const store = configureStore(window.__PRELOADED_STATE__);

const Client = () => {
  return(
    <Provider store={store}>
      <ThemeProvider theme={theme}>
        <CssBaseline />
        <BrowserRouter>
          <App />
        </BrowserRouter>
      </ThemeProvider>
    </Provider>
  );

}


hydrate(
    <Client />,
    document.getElementById('root'),
    () => {
        const jssStyles = document.querySelector('#jss-ssr');

        if (jssStyles) {
            jssStyles.parentElement.removeChild(jssStyles);
        }
    }
);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64495353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档