【问题标题】:Styled-components with components in NextjsNextjs 中带有组件的样式化组件
【发布时间】:2020-11-14 04:41:49
【问题描述】:

我正在设置一个简单的 Nextjs 样板,但似乎无法让样式化组件工作。在我的文件 Header.tsx 中:

// Core Module Imports
import Link from "next/link";
import * as React from "react";

// Styled-Component Imports
import styled from "../theme/theme";

class Header extends React.Component {
    render() {
        return (
            <div>
                <Link href="/about">
                   <a>About Us</a>
                </Link>
            </div>
        );
    }
}

const StyledHeader = styled(Header)`
    width: 100vw;
    height: 10vh;
    background: #2a2c39;
    color: #ff0000;
    link-style: none;
`;

export default StyledHeader;

如您所见,我设置了一个简单的 Header 组件,然后在下面我使用 styled() 来定义我的 css。在我的文件 Index.tsx 中:

// Core Module Imports
import * as React from "react";

import StyledHeader from "../components/Header";

class Index extends React.Component {
    render() {
        return (
            <div>
                <StyledHeader />
                <p>Test Change</p>
                <div>Example Div</div>
            </div>
        );
    }
}

export default Index;

显然我做错了什么,因为它不起作用,我得到的只是一个无样式的链接。谁能指出我正确的方向?

【问题讨论】:

    标签: javascript reactjs typescript styled-components nextjs


    【解决方案1】:

    您需要将this.props.className 传递到Header 的根元素中,以便样式化包装器可以将生成的类名传递到:

    class Header extends React.Component {
        render() {
            return (
                <div className={this.props.className}>
                    <Link href="/about">
                       <a>About Us</a>
                    </Link>
                </div>
            );
        }
    }
    

    【讨论】:

    • 当我这样做时,我收到一个 [ts] 错误,内容为:'Readonly & 只读'.'
    • 我不确定那个错误是什么。我没有太多打字稿经验。你也可以试试&lt;div {...this.props}&gt;
    • 我猜这与打字稿如何处理道具类型有关。您可能必须将className 声明为Header 的道具。我不确定这样做的正确方法是什么。
    • 嗯。好的,我会尝试并报告回来。谢谢!
    • 找到了答案并贴在上面。感谢您的贡献!
    【解决方案2】:

    对于看到此内容并遇到类似问题的任何人,请查看以下内容: https://github.com/zeit/next.js/issues/1942#issuecomment-313925454

    解决了我的问题。

    大家好。在 3.0.1-beta.13+ 版本中,您可以将 passHref 设置为 Link(作为布尔属性)以将其 href 公开给 styled-components(或包装其标签的任何其他库)。

    const StyledLink = styled.a`
      color: red;
      background: blue;
    `
    
    export default ({ href, name }) => (
      <Link prefetch href={href} passHref>
        <StyledLink>{name}</StyledLink>
      </Link>
    )
    

    GitHub 问题中有针对使用next-routes 的人的解决方案。

    【讨论】:

      【解决方案3】:

      TL;DR:

      在您的/pages 文件夹中创建一个_document.js 文件并将其粘贴进去。它应该可以立即工作?

      import Document from 'next/document'
      import { ServerStyleSheet } from 'styled-components'
      
      export default class MyDocument extends Document {
        static async getInitialProps(ctx) {
          const sheet = new ServerStyleSheet()
          const originalRenderPage = ctx.renderPage
      
          try {
            ctx.renderPage = () =>
              originalRenderPage({
                enhanceApp: (App) => (props) =>
                  sheet.collectStyles(<App {...props} />),
              })
      
            const initialProps = await Document.getInitialProps(ctx)
            return {
              ...initialProps,
              styles: (
                <>
                  {initialProps.styles}
                  {sheet.getStyleElement()}
                </>
              ),
            }
          } finally {
            sheet.seal()
          }
        }
      }
      
      

      如果您希望样式化组件在每个页面/组件上自动运行,您“可以创建一个 ServerStyleSheet 并将一个提供程序添加到您的 React 树,它通过上下文 API 接受样式。”在 Nextjs 中,您可以将其添加到您的 _document.js 文件中...

      如果您点击以下链接,您可以了解更多信息:

      1. Styled-Components: SSR Documentation
      2. Nextjs: Customer Render Page

      谢天谢地,已经有一个工作示例,您可以从 styled-components 人员自己那里使用!

      在这里查看:https://github.com/vercel/next.js/blob/canary/examples/with-styled-components/pages/_document.js

      猜你喜欢
      • 1970-01-01
      • 2022-10-19
      • 2021-11-09
      • 2021-09-06
      • 2017-10-23
      • 2020-06-30
      • 2020-09-10
      • 2020-10-27
      • 2018-10-16
      相关资源
      最近更新 更多