警告:道具 `className` 不匹配。当使用带有语义-ui-react 的样式化组件时
Posted
技术标签:
【中文标题】警告:道具 `className` 不匹配。当使用带有语义-ui-react 的样式化组件时【英文标题】:Warning: Prop `className` did not match. when using styled components with semantic-ui-react 【发布时间】:2019-01-18 08:15:39 【问题描述】:我使用此代码将我的 Button 从顶部设置为边缘:
const makeTopMargin = (elem) =>
return styled(elem)`
&&
margin-top: 1em !important;
`;
const MarginButton = makeTopMargin(Button);
每当我使用MarginButton
节点时,我都会收到此错误:Warning: Prop
classNamedid not match. Server: "ui icon left labeled button sc-bwzfXH MjXOI" Client: "ui icon left labeled button sc-bdVaJa fKCkqX"
你可以看到这个产生的here。
我该怎么办?
【问题讨论】:
您共享的链接是指向 IP 地址上的端口 :3000。除非您将该 IP 地址提供给公共流量,并且那里有一个当前正在运行的 Web 服务器,否则没有人将能够访问您正在运行的内容。尝试使用类似代码沙盒的工具创建一个最小的问题示例。 codesandbox.io 对不起,这个 ip 实际上是一个 vps,但由于某种原因它现在没有运行。我现在会尝试重现它。 @brianespinosa 请参阅codesandbox.io/s/xvmq9jjzzq 我正在查看您的控制台,但没有针对 className 的 proptype 警告。 我认为它只发生在开发环境中。我无法在线复制它。 【参考方案1】:通过在项目主文件夹中添加一个 .babelrc 文件为我修复了此警告,其内容如下:
"presets": ["next/babel"],
"plugins": [["styled-components", "s-s-r": true ]]
请参阅以下链接以获取示例: https://github.com/nblthree/nextjs-with-material-ui-and-styled-components/blob/master/.babelrc
【讨论】:
这在我npm i babel-preset-next
之后对我有用
所以这对我有用,但对此有何解释?【参考方案2】:
你应该为 styled-components 安装 babel 插件并在你的 .babelrc 中启用该插件
npm install --save-dev babel-plugin-styled-components
.babelrc
"plugins": [
[
"babel-plugin-styled-components"
]
]
【讨论】:
【参考方案3】://1. I got an error when using material-ui with Next.js
/********************************************* */
//2. The code I imported was like this :
const useStyles = makeStyles(
root: // root must change
width: 100 ,
);
const Footer = () =>
const classes = useStyles();
return (
<div className=classes.root > /* root must change */
<p> footer copyright @2021 </p>
</div>
)
export default Footer;
/********************************************* */
//3. I changed the code like this :
const useStyles = makeStyles(
footer: // changed here to footer
width: "100%",
backgroundColor: "blue !important"
);
const Footer = () =>
const classes = useStyles();
return (
<div className=classes.footer > /* changed here to footer */
<p> footer copyright @2021 </p>
</div>
)
export default Footer;
// I hope it works
【讨论】:
【参考方案4】:如果你已经添加了 babel 插件,请删除 .next 构建文件夹并重新启动服务器
信用:Parth909 https://github.com/vercel/next.js/issues/7322#issuecomment-912415294
【讨论】:
【参考方案5】:Styled components server side rendering
服务器端渲染 styled-components 支持并发服务器 侧面渲染,带有样式表补液。基本思想是 每次在服务器上渲染应用程序时,您都可以创建一个 ServerStyleSheet 并将提供程序添加到您的 React 树,它接受 通过上下文 API 实现样式。
这不会影响全局样式,例如关键帧或 createGlobalStyle 并允许您将样式化组件与 React 一起使用 DOM 的各种 s-s-r API。
import renderToString from 'react-dom/server'
import ServerStyleSheet from 'styled-components'
const sheet = new ServerStyleSheet()
try
const html = renderToString(sheet.collectStyles(<YourApp />))
const styleTags = sheet.getStyleTags() // or sheet.getStyleElement();
catch (error)
// handle error
console.error(error)
finally
sheet.seal()
import renderToString from 'react-dom/server'
import ServerStyleSheet, StyleSheetManager from 'styled-components'
const sheet = new ServerStyleSheet()
try
const html = renderToString(
<StyleSheetManager sheet=sheet.instance>
<YourApp />
</StyleSheetManager>
)
const styleTags = sheet.getStyleTags() // or sheet.getStyleElement();
catch (error)
// handle error
console.error(error)
finally
sheet.seal()
在我使用 nextjs 的情况下
import Document, Head, Main, NextScript from "next/document";
import ServerStyleSheet from "styled-components";
export default class MyDocument extends Document
static getInitialProps( renderPage )
const sheet = new ServerStyleSheet();
const page = renderPage(App => props =>
sheet.collectStyles(<App ...props />)
);
const styleTags = sheet.getStyleElement();
return ...page, styleTags ;
render()
return (
<html>
<Head>this.props.styleTags</Head>
<body>
<Main />
<NextScript />
</body>
</html>
);
【讨论】:
我尝试将 styled-components 添加到我的 Next.js 项目中。它仍然不起作用。我的问题是,当我重新加载 npm run dev 部署的页面时,它会抛出服务器与客户端样式不匹配的错误。我什至使用过 babel-plugin-styled-component 插件。似乎没有任何工作。你能提出一些建议吗?谢谢!【参考方案6】:我遇到了完全相同的问题,通过以下方式解决了:
npm i babel-preset-next
npm install --save -D babel-plugin-styled-components
并将其添加到 .babelrc 文件中:
"presets": ["next/babel"],
"plugins": [["styled-components", "s-s-r": true ]]
【讨论】:
【参考方案7】:PropType 错误是运行时错误,它会让您知道传递给 prop 的预期数据不是预期的。当组件在服务器上呈现和在客户端的 DOM 中呈现时,在组件上设置的 className 属性看起来不一样。
由于您使用的是服务器端渲染,因此您需要确保您的类名是确定性的。该错误向您显示由服务器上的 styled-components
库创建的类以及它与 DOM 的不同之处。对于通常没有确定性类名的库,您需要查看高级配置。 Take a look at the styled-components documentation regarding specificity as it pertains to s-s-r.
【讨论】:
【参考方案8】:我已经按照这些步骤解决了这个问题。
-
在根目录下创建一个名为
.babelrc
的文件,并配置.babelrc
文件。
删除 .next 构建文件夹(它存储一些缓存)。
重启服务器。
热重载浏览器。
.babelrc
配置文件
"presets": [
"next/babel"
],
"plugins": [
[
"styled-components",
"s-s-r": true,
"displayName": true,
"preprocess": false
]
]
【讨论】:
【参考方案9】:或者您可以将其添加到您的next.config.js
。这也使得 next-swc (speedy web compiler) 可以减少构建时间。见more here。
// next.config.js
module.exports =
experimental:
// Enables the styled-components SWC transform
styledComponents: true
【讨论】:
【参考方案10】:如果你使用 create-react-app,你可以使用这个解决方案。
名为 styled.ts 的文件
import styled from 'styled-components/macro';
import css from 'styled-components';
export const ListRow = styled.div`
...
...
`
根据文件名,前缀如下。
`$file_name__styled_component_name $unique_id`
实现时的含义它将具有以下类名
虽然指定第一个前缀的来源会很好,这意味着我们使用文件夹名称而不是文件名。我目前不知道它的解决方案。
【讨论】:
以上是关于警告:道具 `className` 不匹配。当使用带有语义-ui-react 的样式化组件时的主要内容,如果未能解决你的问题,请参考以下文章
Next.Js 带有样式组件的 React 应用程序。警告:道具 `className` 不匹配。服务器:“x” 客户端:“y”
react-dom.development.js?61bb:530 警告:道具类名不匹配
react-select:如何解决“警告:道具`id`不匹配”
在一个组件中使用 formik-material-ui TextField 和 material-ui TextField 时出现“警告:Prop `className` 不匹配...”