【问题标题】:Warning: Prop `className` did not match. when using styled components with semantic-ui-react警告:道具 `className` 不匹配。当使用带有语义-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: PropclassNamedid 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 警告。
  • 我认为它只发生在开发环境中。我无法在线复制它。

标签: reactjs jsx styled-components semantic-ui-react next.js


【解决方案1】:

通过在项目主文件夹中添加一个 .babelrc 文件为我修复了此警告,其内容如下:

{
  "presets": ["next/babel"],
  "plugins": [["styled-components", { "ssr": 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 的各种 SSR 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", { "ssr": true }]]
        }
        

        【讨论】:

          【解决方案7】:

          PropType 错误是运行时错误,它会让您知道传递给 prop 的预期数据不是预期的。当组件在服务器上呈现和在客户端的 DOM 中呈现时,在组件上设置的 className 属性看起来不一样。

          由于您使用的是服务器端渲染,因此您需要确保您的类名是确定性的。该错误向您显示由服务器上的 styled-components 库创建的类以及它与 DOM 的不同之处。对于通常没有确定性类名的库,您需要查看高级配置。 Take a look at the styled-components documentation regarding specificity as it pertains to SSR.

          【讨论】:

            【解决方案8】:

            我已经按照这些步骤解决了这个问题。

            1. 在根目录下创建一个名为.babelrc的文件,并配置.babelrc文件。
            2. 删除 .next 构建文件夹(它存储一些缓存)。
            3. 重启服务器。
            4. 热重载浏览器。

            .babelrc配置文件

            {
                "presets": [
                    "next/babel"
                ],
                "plugins": [
                    [
                        "styled-components",
                        {
                            "ssr": 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}`
                

                实现时的含义它将具有以下类名

                虽然指定第一个前缀的来源会很好,这意味着我们使用文件夹名称而不是文件名。我目前不知道它的解决方案。

                【讨论】:

                  猜你喜欢
                  • 2019-08-01
                  • 2021-01-27
                  • 2021-03-30
                  • 2018-03-11
                  • 2018-11-14
                  • 2019-10-12
                  • 2018-04-28
                  相关资源
                  最近更新 更多