React 服务器端渲染与 Express - 客户端校验和和样式上的警告



我是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/reaeact-reaect-router-materialui-serversiderendering

'警告:js:44沃宁:React试图在容器中重复使用标记 但是校验和无效。这通常意味着您正在使用 服务器渲染和服务器上生成的标记不是什么 客户期待的。反应注入新的标记以补偿 哪个有效,但您失去了服务器的许多好处 渲染。相反,弄清楚为什么要生成的标记为 客户端或服务器上的不同:(客户端) 0; text-align:中心; MUI准备:; Webki(Server) 0; text-align:中心; -webkit-user-select:'

在此razzle材料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>
        )
    }
}

它运行良好,我认为这也是正确的。

材料-UI及其对造型元素的内联方法,对服务器端渲染具有此陷阱:

在客户端上,材料图渲染仅添加了运行应用程序的浏览器特定的内联样式。但是在服务器上,您不在浏览器中,因此如何知道要使用哪种特定样式规则,以使渲染的HTML匹配客户端渲染的HTML并避免反应警告?

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

这是来自他们的Serveride渲染文档:

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:中心; -webkit-user-select:

您会注意到,两者之间的差异是服务器渲染中不存在的额外mui-prepared。在文档中的服务器渲染指南的底部,有一个关于此的注释。

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

看起来您只有服务器上的process.env.NODE_ENV=production(我是这种情况)。

最新更新