【问题标题】:Cannot use mui theme with emotion css prop无法使用带有情感 css 道具的 mui 主题
【发布时间】:2022-08-08 18:03:07
【问题描述】:

我正在尝试在 Web 应用程序中实现一个深色主题,并将我的样式从仅使用 !important 覆盖的 styles.css 移动到情感 css 道具。

这是来自 App.tsx 的代码,我在其中创建主题并使用 ThemeProvider

const theme = createTheme({
  typography: {
    allVariants: {
      fontFamily: \'SFCompactDisplay\',
    },
  },
  palette: {
    primary: {
      main: \'#0052cc\',
    },
  },
});

console.log(theme);

const App: React.FC = () => (
  <ThemeProvider theme={theme}>
    <Switch>
      <Route path=\"/login\" component={Login} exact />
      <ProtectedRoute path=\"/\" component={Dashboard} exact />
      {/* <Route path=\"/register\" component={Register} /> */}
      <Redirect to=\"/\" />
    </Switch>
    <Toaster
      position=\"top-right\"
      toastOptions={{
        style: {
          fontWeight: 400,
        },
      }}
    />
  </ThemeProvider>
);

另外,这里是来自 css.ts 的代码,然后我在其中一个组件中使用

export const splitContainer = (theme) => {
  console.log(theme);
};

export const content: CSSWithTheme = (theme) => ({
  maxWidth: \'800px\',
  width: \'100%\',
  [theme.breakpoints.down(\'md\')]: {
    padding: \'0 24px\',
    maxWidth: \'100%\',
  },
});

我收到一条错误消息,指出主题的任何属性都未定义。我安慰记录了两个主题,第一个主题在 App 中看起来像带有断点、调色板属性的普通 MUI 主题,但在 css.ts 中的主题看起来像这样:

我在仪表板组件中使用 splitContainer

  return (
    <Box css={css.splitContainer}>
      <SideBar tab={tab} setTab={setTab} />
      <Box className=\"container-main-overview\">
        {tab === 1 && <MachineList />}
        {tab === 4 && <AddInstance />}
        {tab === 5 && <Support />}
      </Box>
    </Box>
  );

样式有效,但是当我尝试使用主题时,出现未定义的错误

  • 请在您使用CSSWithThemesplitContainer 的地方显示代码。
  • @RyanCogswell 我在 App 中渲染的组件之一中使用它。 return ( <Box css={css.splitContainer}> <SideBar tab={tab} setTab={setTab} /> <Box className=\"container-main-overview\"> {tab === 1 && <MachineList / >} {tab === 4 && <AddInstance />} {tab === 5 && <Support />} </Box> </Box> );
  • 除了 MUI ThemeProvider 之外,您还需要使用 @emotion/react ThemeProvider 指定主题。

标签: reactjs typescript material-ui emotion


【解决方案1】:

根据@Ryan Cogswell 提到的,您还需要声明 Emotion 主题提供程序。由于 Emotion 的主题是一个空对象,因此您可以按原样传递 MUI 主题。如果你使用打字稿,你需要extend emotion's theme interface. 如果你需要处理暗模式,你可以有自己的主题提供者(基于 React 的上下文 API)来切换明暗主题,并结合上面提到的两个,MUI 和情感提供者。

这是上下文提供者的一个小例子(没有上下文定义)

const ThemeProvider: FC<ThemeProviderProps> = ({ children }) => {
  const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
  const defaultTheme = useMemo<ThemeContextProps['themeMode']>(
    () => (prefersDarkMode ? 'dark' : 'light'),
    [prefersDarkMode],
  );

  const [themeMode, setThemeMode] =
    useState<ThemeContextProps['themeMode']>(defaultTheme);

  const toggleTheme = useCallback(() => {
    setThemeMode((prevValue) => 
      (prevValue === 'light' ? 'dark' : 'light'));
  }, []);

  const providerProps = useMemo(
    () => ({
      themeMode,
      theme: themeMode === 'light' ? lightTheme : darkTheme,
      toggleTheme,
    }),
    [themeMode, toggleTheme],
  );

  return (
    <ThemeContext.Provider value={providerProps}>
      <MuiThemeProvider theme={providerProps.theme}>
        <EmotionThemeProvider theme={providerProps.theme}>
          {children}
        </EmotionThemeProvider>
      </MuiThemeProvider>
    </ThemeContext.Provider>
  );
}

【讨论】:

    猜你喜欢
    • 2021-12-06
    • 2021-06-19
    • 2021-11-17
    • 2020-08-27
    • 2022-07-24
    • 2022-10-20
    • 2021-11-13
    • 2021-07-05
    • 2022-06-14
    相关资源
    最近更新 更多