【发布时间】:2020-06-02 23:36:25
【问题描述】:
react-dom.development.js?61bb:530 警告:道具className 不匹配。
服务器:“MuiTypography-root makeStyles-root-32 makeStyles-root-47 makeStyles-darkest-27 makeStyles-bodySmall-43 makeStyles-noTextTransform-41 MuiTypography-body1” 客户端:“MuiTypography-root makeStyles-root-32 makeStyles-root-48 makeStyles-darkest-27 makeStyles-bodySmall-43 makeStyles-noTextTransform-41 MuiTypography-body1”
到目前为止,我尝试了以下方法无济于事:
- 在 webpack 中配置运行时块,因为我们在路由级别进行代码拆分,
optimization: {
runtimeChunk: {
name: 'app',
},
},
已验证material-ui只有一个版本,最新,4.9.3
客户端和服务器的节点环境相同
尝试使用新的 createGenerateClassName 将客户端和应用程序包装在 stylesprovider 中:
服务器:
const sheets = new ServerStyleSheets();
const generateClassName = createGenerateClassName({
productionPrefix: 'tock',
});
const html = ReactDomServer.renderToString(
sheets.collect(
<Provider store={store}>
<StaticRouter location={req.url} context={routerContext}>
<StylesProvider generateClassName={generateClassName}>
<Application />
</StylesProvider>
</StaticRouter>
</Provider>
)
);
以及确保在每次请求时创建新的ServerStyleSheets。
客户:
const generateClassName = createGenerateClassName({
productionPrefix: 'tock',
});
try {
(fullRender ? ReactDOM.render : ReactDOM.hydrate)(
<StrictMode>
<Provider store={store}>
<Router history={tockHistory}>
<StylesProvider generateClassName={generateClassName}>
<Routes />
</StylesProvider>
</Router>
</Provider>
</StrictMode>,
document.querySelector('#Root')
);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
throw e;
}
遵循参考实现: https://material-ui.com/guides/server-rendering/
这似乎只发生在开发模式下。如果我捆绑生产并运行该应用程序,它就可以工作。
通过: https://material-ui.com/getting-started/faq/#my-app-doesnt-render-correctly-on-the-server
具体来说,我对此感兴趣: https://material-ui.com/getting-started/faq/#react-class-name-hydration-mismatch
节点:v13.8.0 网络包:4.41.6 Material-ui:4.9.3
有趣的是,我们开始看到这个问题的组件使用了一些基于 prop 的样式:
export const useTypographyStyles = makeStyles((theme) => ({
root: {
marginBottom: ({ mb, paragraph }: TypographyProps) =>
paragraph ? theme.spacing(2) : theme.spacing(mb ?? 0),
},
我注意到它为钩子中的类生成了 2 个字符串。
root: "makeStyles-root-32 makeStyles-root-232"
是我在记录以下结果时得到的:
const classes = useTypographyStyles({ mb, paragraph });
但是如果我在那里只用一个值做一个常规样式,我就不明白这个问题。
【问题讨论】:
-
也发在material-ui github:github.com/mui-org/material-ui/issues/19772
-
我也尝试了
withStyles和createStyles的组合,结果还是一样。 -
还有更多信息是我也在使用 webpack 来编译后端。
标签: material-ui