簡體   English   中英

使用Express進行React Server端渲染-客戶端校驗和樣式警告

[英]React Server side rendering with Express - warning on the client checksum & Styling

我是React服務器端渲染的新手,正在使用React , Redux , React router , Material UI進行小型演示。 我面臨的問題是以下警告。 不確定同構樣式和資源如何與webpack一起使用。

我了解管道服務器端渲染的工作方式,如果有誤,請糾正我。

  • 使用renderToString,React組件解析為HTML。
  • HTML在客戶端上渲染后,所有事件,樣式都會被附加起來,這意味着react會嘗試再次在客戶端上渲染組件,如果已經創建了組件,它將再次創建它。
  • 如果組件已經創建或不是基於校驗和派生的。

GIT中報告的問題https://github.com/callemall/material-ui/issues/4466

代碼https://github.com/sabha/React-Redux-Router-MaterialUI-ServerSideRendering

'warning.js:44警告:React嘗試重用容器中的標記,但校驗和無效。 通常,這意味着您正在使用服務器呈現,並且服務器上生成的標記不是客戶端期望的。 React注入了新的標記來補償可以正常工作的標記,但是您已經失去了服務器渲染的許多好處。 相反,要弄清為什么生成的標記在客戶端或服務器上不同的原因:(client)0; text-align:center; mui-prepared:;-webki(server)0; text-align:center; -webkit-user -選擇:'

在此Razzle Material UI樣式示例項目中,我通過以下方式設置用戶代理:

server.js

renderToString(<Application userAgent={request.headers['user-agent']} />)

client.js

hydrate(<Application userAgent={navigator.userAgent} />, document.getElementById('root'))

Main.js

class Main extends Component {
    constructor(properties, context) {
        super(properties, context)

        this.muiTheme = getMuiTheme({
            userAgent: properties.userAgent
        })
    }

    render() {
        return (
            <MuiThemeProvider muiTheme={this.muiTheme}></MuiThemeProvider>
        )
    }
}

它運作良好,我也認為它是正確的。

Material-UI采用內聯樣式的樣式元素設計方法,在服務器端渲染方面具有以下陷阱:

在客戶端上,MaterialUI渲染僅添加特定於正在運行應用程序的瀏覽器的內聯樣式。 但是在服務器上,您不在瀏覽器中,那么如何知道要使用哪種特定樣式規則,以使呈現的HTML與客戶端呈現的HTML匹配並避免出現React警告?

他們有關於如何解決問題的文檔。 從本質上講,這意味着確保在進行服務器端呈現之前,設置用戶代理字符串(從HTTP請求標頭捕獲)。

這來自他們的服務器端渲染文檔

import getMuiTheme from 'material-ui/getMuiTheme';
import MuiThemeProvider from 'material-ui/MuiThemeProvider';
import {green100, green500, green700} from 'material-ui/styles/colors';

const muiTheme = getMuiTheme({
  palette: {
    primary1Color: green500,
    primary2Color: green700,
    primary3Color: green100,
  },
}, {
  avatar: {
    borderColor: null,
  },
  userAgent: req.headers['user-agent'],
});

class Main extends React.Component {
  render() {
    return (
      <MuiThemeProvider muiTheme={muiTheme}>
        <div>Hello world</div>
      </MuiThemeProvider>
    );
  }
}

(客戶)0; text-align:center; mui准備: ; -webki
(服務器)0;文本對齊:中心; -webkit用戶選擇:

您會注意到,兩者之間的區別是由mui-prepared ,這是服務器渲染中不存在的。 在文檔中的服務器渲染指南的底部有關於此的注釋。

為了確保樣式轉換僅應用一次,我們在process.env.NODE_ENV!=='production'時向每個樣式添加一個附加屬性。

看起來您僅在服務器上具有process.env.NODE_ENV=production (對我來說就是這種情況)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM