React + Material-UI-警告:道具className不匹配 [英] React + Material-UI - Warning: Prop className did not match

查看:296
本文介绍了React + Material-UI-警告:道具className不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于classNames的分配方式不同,我很难在Material-UI组件中的客户端和服务器端样式渲染之间出现差异.

I'm having difficulty with differences between client-side and server-side rendering of styles in Material-UI components due to classNames being assigned differently.

在第一次加载页面时,正确分配了className,但是刷新页面后,classNames不再匹配,因此组件将失去其样式.这是我在控制台上收到的错误消息:

The classNames are assigned correctly on first loading the page, but after refreshing the page, the classNames no longer match so the component loses its styling. This is the error message I am receiving on the Console:

警告:道具className不匹配. 服务器:"MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-31 " 客户端:"MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-2 "

Warning: Prop className did not match. Server: "MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-31" Client: "MuiFormControl-root-3 MuiFormControl-marginNormal-4 SearchBar-textField-2"

我遵循了Material-UI文本字段示例文档及其随附的内容代码沙箱示例,但我似乎无法弄清楚是什么原因导致服务器和客户端之间的差异类名.

I've followed the Material-UI TextField example docs, and their accompanying Code Sandbox example, but I can't seem to figure out what is causing the difference between the server and client classNames.

在添加带有删除"x"图标的Material-UI芯片时,我遇到了类似的问题.刷新后呈现的"x"图标宽度达到了惊人的1024像素.同样的潜在问题是该图标没有收到正确的样式类.

I experienced a similar issue when adding Material-UI Chips with a delete 'x' icon. The 'x' icon rendered with a monstrous 1024px width after refreshing. The same underlying issue being that icon was not receiving the correct class for styling.

关于堆栈溢出,有几个问题解决了为什么客户端和服务器可能以不同的方式呈现类名(例如,需要使用自定义server.js并使用Math升级到@ Material-UI/core版本^ 1.0.0).在setState中是随机的),但对于我而言,这些都不适用.

There are a few questions on Stack Overflow addressing why the client and server might render classNames differently (e.g. need to upgrade to @Material-UI/core version ^1.0.0, using a custom server.js, and using Math.random in setState), but none of these apply in my case.

我不知道是否要此Github讨论可能会有所帮助,但可能没有帮助,因为他们使用的是Material-UI的Beta版.

I don't know enough to tell whether this Github discussion might help, but likely not since they were using a beta version of Material-UI.

创建项目文件夹并启动节点服务器:

Create project folder and start Node server:

mkdir app
cd app
npm init -y
npm install react react-dom next @material-ui/core
npm run dev

编辑package.json:

添加到脚本":"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

app/components/SearchBar.jsx:

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中访问页面,并看到以下内容:

Visit page in browser localhost:3000 and see this:

TextField组件周围的红色边框

刷新浏览器并看到以下内容:

Refresh the browser and see this:

TextField组件的样式消失了

请注意,TextField周围的红色边框消失了.

Notice that the red border around TextField disappears.

  • 反应":16.4.0
  • 反应堆":16.4.0
  • 下一个":6.0.3
  • "@ material-ui/core":1.2.0

推荐答案

问题是服务器端生成类名,但是样式表不会自动包含在HTML中.您需要显式提取CSS,并将其附加到服务器端呈现的组件的UI中.整个过程的说明如下: https://material-ui.com/guides/server-rendering /

The issue is the server side generates the class names but style sheets are not automatically included in the HTML. You need to explicitly extract the CSS and append it to the UI for the server side rendered components. The whole process is explained here: https://material-ui.com/guides/server-rendering/

这篇关于React + Material-UI-警告:道具className不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆