【问题标题】:React Server side rendering with Express - warning on the client checksum & Styling使用 Express 反应服务器端渲染 - 客户端校验和和样式上的警告
【发布时间】:2016-10-15 11:31:38
【问题描述】:

我是 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:44Warning: React 试图在容器中重用标记 但校验和无效。这通常意味着您正在使用 服务器渲染和服务器上生成的标记不是什么 客户期待。 React 注入了新的标记来弥补 哪个有效,但您失去了服务器的许多好处 渲染。相反,弄清楚为什么生成的标记是 客户端或服务器上的不同:(客户端) 0;text-align:center;mui-prepared:;-webki (服务器) 0;text-align:center;-webkit-user-select:'

【问题讨论】:

标签: javascript reactjs webpack material-ui


【解决方案1】:

在这个Razzle Material UI Styled Example 项目中,我这样设置用户代理:

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>
        )
    }
}

效果很好,我也觉得是对的。

【讨论】:

    【解决方案2】:

    (client) 0;text-align:center;mui-prepared:;-webki
    (服务器) 0;text-align:center;-webkit-user-select:

    您会注意到两者之间的区别在于服务器渲染中不存在额外的mui-prepared。在文档中server rendering guide 的底部有一个说明。

    为了确保我们的样式转换只应用一次,我们在 process.env.NODE_ENV !== 'production' 时为每个样式添加了一个附加属性。

    您似乎只在服务器上拥有process.env.NODE_ENV=production(我就是这种情况)。

    【讨论】:

    • 嗨,我在开发中运行 Racket 样板时遇到此错误,我应该更改 process.env 否则此错误将在生产中消失。谢谢
    • @Matt Cole 将 NODE_ENV 设置为生产环境会彻底改变一切。
    【解决方案3】:

    Material-UI 采用内联样式方法来设置元素样式,在服务器端渲染方面存在以下问题:

    在客户端,MaterialUI 渲染仅添加特定于运行应用程序的浏览器的内联样式。但是在服务器上,您不在浏览器中,那么如何知道使用哪个 特定样式规则,以便呈现的 HTML 与客户端呈现的 HTML 匹配并避免 React 警告?

    他们有关于如何解决问题的文档。本质上,这意味着确保在进行服务器端渲染之前设置用户代理字符串(从 HTTP 请求标头中捕获)。

    这是来自他们的serverside rendering documentation

    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>
        );
      }
    }
    

    【讨论】:

    • 谢谢@Brandon。在我的server.js 文件中,我传递了我在快速请求标头const muiTheme = getMuiTheme({userAgent: req.headers['user-agent']}); 中收到的用户代理。
    猜你喜欢
    • 1970-01-01
    • 2016-02-19
    • 2017-12-29
    • 2017-03-16
    • 2015-05-09
    • 1970-01-01
    • 2017-01-08
    • 2016-08-19
    • 2015-09-06
    相关资源
    最近更新 更多