ClassNamesの割り当てが異なるため、Material-UIコンポーネントのスタイルのクライアント側とサーバー側のレンダリングの違いに問題があります。
ClassNamesは最初のページのロード時に正しく割り当てられますが、ページを更新した後、classNamesは一致しなくなり、コンポーネントはそのスタイルを失います。これは、コンソールに表示されるエラーメッセージです。
警告:プロップ
className
が一致しませんでした。サーバー: "MuiFormControl-root-3 MuiFormControl-marginNormal-4SearchBar-textField-31"クライアント: "MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-2 "
Material-UI TextField example docs とそれに付随する Code Sandbox example をフォローしましたが、サーバーの違いの原因がわからないようですおよびクライアントのclassNames。
削除 'x'アイコンが付いたMaterial-UIチップを追加するときに、同様の問題が発生しました。リフレッシュ後、1024xの巨大な幅でレンダリングされた「x」アイコン。同じ根本的な問題は、そのアイコンがスタイリングの正しいクラスを受け取っていなかったことです。
Stack Overflowについて、クライアントとサーバーがclassNamesを異なる方法でレンダリングする可能性がある理由(たとえば、@ Material-UI/coreバージョン^ 1.0.0にアップグレードする必要がある、カスタムserver.jsを使用する、setStateでMath.randomを使用する)についていくつか質問があります。 )、しかしこれらのどれも私の場合には適用されません。
このGithubディスカッション が役立つかどうかはわかりませんが、Material-UIのベータ版を使用していたので、おそらく役に立ちません。
プロジェクトフォルダを作成し、Node server:
mkdir app
cd app
npm init -y
npm install react react-dom next @material-ui/core
npm run dev
「スクリプト」に追加:"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
そしてこれを見てください:
ブラウザを更新してこれを見てください:
TextFieldの周りの赤い境界線が消えていることに注意してください。
問題は、サーバー側がクラス名を生成するが、スタイルシートがHTMLに自動的に含まれないことです。 CSSを明示的に抽出し、サーバー側のレンダリングされたコンポーネントのUIに追加する必要があります。プロセス全体をここで説明します: https://material-ui.com/guides/server-rendering/