【问题标题】:Nextjs with Styled components not passing theme带有样式组件的 Nextjs 不通过主题
【发布时间】:2021-11-09 07:17:36
【问题描述】:

我正在尝试在我的 Next.js 项目中将我的主题对象传递给 styled-components,但它一直无法将其作为道具接收。

那是我的_document.tsx

import { getInitialProps } from "@expo/next-adapter/document";
import Document,  { DocumentContext, DocumentInitialProps }  from "next/document";
import { ServerStyleSheet } from "styled-components";

export default class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext): Promise<DocumentInitialProps> {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;

    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: (App) => (props) =>
            sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }
}

之后我用ThemeProvider包裹了我的_app.tsx

import Layout from '../components/Layout'
import 'setimmediate';
import { ThemeProvider } from 'styled-components';
import { wrapperStore } from "../store";
import { ApolloProvider } from "@apollo/client";
import client from './api/apollo-client';
import React from 'react';
import lightTheme from '../helpers/light-mode';
import { AppProps } from 'next/app';

function MyApp({ Component, pageProps }: AppProps) {

  return (
    <React.Fragment>
    <ApolloProvider client={client}>
      <ThemeProvider theme={lightTheme}>
        <Layout>
          <Component {...pageProps} />
        </Layout>
      </ThemeProvider>
     </ApolloProvider>
    </React.Fragment>
  )
}
export default wrapperStore.withRedux(MyApp);

当我尝试包装我的组件并导出它withTheme时,我会收到一个警告@

[withTheme] You are not using a ThemeProvider nor passing a theme prop or a theme in defaultProps in component class "Connect(Front)"

当我尝试从我的道具控制台记录theme 时,它返回未定义,当我创建样式组件时,尝试使用theme 作为道具时会导致错误

export const RecruitmentTextLocation = styled.Text`
    fontSize: ${scaleFont(15)};
    textAlign: left;
    marginTop: ${scale(5)}px;
    marginBottom: ${scale(1)}px;
    fontFamily: roboto;
    fontWeight: 500;
    color: ${({theme}) => theme.colors.cardTitleColor};
`;

TypeError: Cannot read property 'colors' of undefined

我真的很纠结如何在 Nextjs 上将主题与样式化组件一起使用。

【问题讨论】:

    标签: react-native next.js styled-components


    【解决方案1】:

    我想您的问题出在 light-mode.tsx 中。我怎么能看到你使用 typescript 在这种情况下需要创建一个 declarations 文件DefaultTheme 接口。 example

    创建声明文件 从 v4.1.4 版本的定义开始,可以通过使用声明合并来扩展样式组件的 TypeScript 定义。 documentation

    light-mode.tsx

    import { DefaultTheme } from 'styled-components';
    
    export const lightTheme: DefaultTheme = {
      colors: {
        cardTitleColor: red;
      }
    };
    

    【讨论】:

      【解决方案2】:

      我一直在寻找相同的解决方案,并找到了一种解决方案,可以在样式化组件上键入您收到的作为道具的 theme 对象。

      首先,导出你的主题类型,例如:

      export type LightTheme = typeof lightTheme;
      

      然后使用以下内容添加src/declaration.d.ts 文件,以便增强由styled-components 导出的DefaultTheme 以使用您的自定义主题对象键入:

      import { Theme } from "globalStyles";
      
      declare module "styled-components" {
        export interface DefaultTheme extends Theme {}
      }
      

      从那里您将不需要任何withTheme 来使用您的主题对象,因为您只需通过以下方式访问它:

      color: ${({theme}) => theme.colors.cardTitleColor};
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-03-24
        • 2017-07-01
        • 2021-09-06
        • 2020-05-08
        • 1970-01-01
        • 2021-08-06
        • 2020-06-30
        相关资源
        最近更新 更多