尝试将MaterialUI主题道具传递给样式化组件时为“未定义”

时间:2020-09-30 09:23:23

标签: reactjs typescript material-ui styled-components

我试图在样式化的组件中访问我的Material-UI主题道具,但是我一直在获取...

TypeError: Cannot read property 'primary' of undefined或浏览器中的类似错误。

这是我的自定义主题(index.ts

import { createMuiTheme } from "@material-ui/core";
import { blue } from "@material-ui/core/colors";

const theme = createMuiTheme({
    palette: {
      primary: {
        main: blue[800],
        contrastText: "#FFF"
      },
      secondary: {
        main: blue[600],
        contrastText: "#FFF"
      }
    },
    typography : {
        fontFamily: [
            "Nunito",
            "Roboto",
        ].join(",") 
    }
});

export default theme;

这是我的主题将应用程序包装在App.tsx

中的位置
// Other imports
import theme from "../../app/theme/index";

const App: React.FC = () => {
    return (
        <>
            <StylesProvider injectFirst>
                <ThemeProvider theme={theme}>
                    // Routing stuff
                </ThemeProvider>
            </StylesProvider>
        </>
    );
};

export default App;

这是我尝试使用样式化组件的地方

import { ListItem } from "@material-ui/core";
import React from "react";
import styled from "styled-components";

const Brand = styled(ListItem)`
    background-color: ${props => props.theme.palette.primary.dark},
    padding: ${props => props.theme.spacing(1)},
    font-size: ${props => props.theme.typography.h6.fontSize},
    font-weight: ${props => props.theme.typography.fontWeightMedium},
    color: "white",
    min-height: "64px",
    padding-left: ${props => props.theme.spacing(6)}
`;

const SidebarNew: React.FC = () => {

    return (
        <Brand button>
            // Stuff
        </Brand>
    );
};

export default SidebarNew;

这可以编译,但在浏览器中失败。我在这里想念什么?

如果我使用如下所示的styled内置的material-ui,它似乎可以工作,但是我更喜欢直接使用styled-components

const Brand = styled(ListItem)(({ theme }) => ({
    backgroundColor: theme.palette.primary.dark,
    padding: theme.spacing(1),
    fontSize: theme.typography.h6.fontSize,
    fontWeight: theme.typography.fontWeightMedium,
    color: "white",
    minHeight: 64,
    paddingLeft: theme.spacing(6)
}));

1 个答案:

答案 0 :(得分:2)

除了Material-UI ThemeProvider外,还需要使用样式组件中的SCThemeProvider(在下面的示例中为ThemeProvider);否则,样式化的组件将不了解您的主题。

这是一个可行的示例:

import {
  createMuiTheme,
  StylesProvider,
  ThemeProvider
} from "@material-ui/core";
import { ThemeProvider as SCThemeProvider } from "styled-components";
import * as React from "react";
import Dashboard from "./Dashboard";
import "./styles.css";

const theme = createMuiTheme({
  palette: {
    primary: {
      main: "#1a1aff",
      contrastText: "#FFF"
    },
    secondary: {
      main: "#ff3333",
      contrastText: "#FFF"
    }
  },
  typography: {
    h5: {
      fontSize: "10px"
    }
  }
});

export default function App() {
  return (
    <StylesProvider injectFirst>
      <ThemeProvider theme={theme}>
        <SCThemeProvider theme={theme}>
          <Dashboard />
        </SCThemeProvider>
      </ThemeProvider>
    </StylesProvider>
  );
}

Edit Material-UI Theme (forked)