由于classNames的分配方式不同,我在Material-UI组件中的客户端和服务器端样式渲染之间存在差异。
第一次加载页面时会正确分配className,但是刷新页面后,className将不再匹配,因此组件将失去其样式。这是我在控制台上收到的错误消息:
警告:道具className不匹配。服务器:“ MuiFormControl-root-3 MuiFormControl- marginNormal-4 SearchBar-textField-31 ”客户端:“ MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-2 ”
className
我遵循了Material-UI TextField 示例文档及其随附的代码沙箱示例,但是我似乎无法弄清楚是什么原因导致服务器类和客户端类名之间的差异。
在添加带有删除“ x”图标的Material-UI芯片时,我遇到了类似的问题。刷新后呈现的“ x”图标宽度达到了惊人的1024px。同样的潜在问题是该图标没有收到正确的样式类。
关于堆栈溢出,有几个问题解决了为什么客户端和服务器可能会以不同的方式呈现className(例如,需要使用自定义server.js并在setState中使用Math.random升级到@ Material-UI / core版本^ 1.0.0) ),但这些都不适用于我的情况。
我还不知道该Github讨论是否会有所帮助,但由于他们使用的是Material-UI的Beta版,因此可能没有帮助。
创建项目文件夹并启动节点服务器:
mkdir app cd app npm init -y npm install react react-dom next @material-ui/core npm run dev
添加到“脚本”: "dev": "next",
"dev": "next",
import Head from "next/head" import CssBaseline from "@material-ui/core/CssBaseline" import SearchBar from "../components/SearchBar" const Index = () => ( <React.Fragment> <Head> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta charSet="utf-8" /> </Head> <CssBaseline /> <SearchBar /> </React.Fragment> ) export default Index
import PropTypes from "prop-types" import { withStyles } from "@material-ui/core/styles" import TextField from "@material-ui/core/TextField" const styles = (theme) => ({ container: { display: "flex", flexWrap: "wrap", }, textField: { margin: theme.spacing.unit / 2, width: 200, border: "2px solid red", }, }) class SearchBar extends React.Component { constructor(props) { super(props) this.state = { value: "" } this.handleChange = this.handleChange.bind(this) this.handleSubmit = this.handleSubmit.bind(this) } handleChange(event) { this.setState({ value: event.target.value }) } handleSubmit(event) { event.preventDefault() } render() { const { classes } = this.props return ( <form className={classes.container} noValidate autoComplete="off" onSubmit={this.handleSubmit} > <TextField id="search" label="Search" type="search" placeholder="Search..." className={classes.textField} value={this.state.value} onChange={this.handleChange} margin="normal" /> </form> ) } } SearchBar.propTypes = { classes: PropTypes.object.isRequired, } export default withStyles(styles)(SearchBar)
在浏览器中访问页面localhost:3000并看到以下内容:
localhost:3000
TextField组件周围的红色边框
刷新浏览器,然后看到以下内容:
TextField组件的样式消失了
请注意,TextField周围的红色边框消失了。
问题是服务器端生成类名,但是样式表不会自动包含在HTML中。您需要显式提取CSS并将其附加到服务器端渲染组件的UI中。整个过程在这里进行了说明:https://material-ui.com/guides/server- rendering/