我是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
(我是这种情况)。