使用Express进行React Server端渲染 - 在客户端校验和&造型

时间:2016-06-14 16:02:46

标签: javascript reactjs webpack material-ui

我是React服务器端渲染的新手,正在使用React , Redux , React router , Material UI进行小型演示。我面临的问题是以下警告。不确定同构样式和资产如何与webpack一起使用。

我理解管道如何在服务器端渲染工作,请纠正我,如果它是错误的。

  • 使用renderToString将React组件解析为HTML。
  • 一旦HTML呈现在客户端,所有事件,样式都附加意味着反应尝试再次在客户端呈现组件,如果组件已经创建,它将再次创建它。
  • 如果已经创建了组件,或者基于校验和派生了NOT。

GIT报告的问题 https://github.com/callemall/material-ui/issues/4466

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

  

'warning.js:44警告:React试图在容器中重用标记   但校验和无效。这通常意味着您正在使用   服务器渲染和服务器上生成的标记不是什么   客户期待。 React注入新的标记来补偿   哪个有效,但你失去了服务器的许多好处   渲染。相反,找出生成标记的原因   在客户端或服务器上不同:(客户端)   0; text-align:center; mui-prepared:; - webki(server)   0;文本对齐:中心; -webkit-用户选择:“

3 个答案:

答案 0 :(得分:3)

在这个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>
        )
    }
}

效果很好,我认为也是正确的。

答案 1 :(得分:1)

Material-UI采用内联风格的样式元素方法,在服务器端呈现方面有这个问题:

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

他们有关于如何解决问题的文档。本质上,它意味着确保在进行服务器端呈现之前设置用户代理字符串(从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>
    );
  }
}

答案 2 :(得分:1)

  

(客户端)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(对我来说就是这种情况)。