【问题标题】:How can I use useTheme in Material UI 5?如何在 Material UI 5 中使用 useTheme?
【发布时间】:2021-12-05 23:44:39
【问题描述】:

我刚开始使用 Material UI 5.0.4(使用 styled-components),我想在组件中访问主题。我在网上看到useTheme,所以我检查了文档和found it - @mui/styles/useTheme。但是,它是遗留文档,而 @mui/styles 在 MUI 5 中不存在。所以,我查看了 @mui/system,然后找到了 the section "Accessing the theme in a component"。但是,这只是指向遗留文档!

在文档似乎对我没有帮助之后,我决定使用 Visual Studio Code 的“快速修复”功能,如果您将鼠标悬停在该功能上,VSCode 将为您提供要导入的选项列表。以下是我尝试过的选项列表,以及它们不起作用的原因:

  • @mui/material/styles/useTheme - 返回默认主题对象,无论如何。查看源代码,this is literally what it does - 它切换到默认主题,然后返回主题。
  • @mui/material/private-theming/useTheme - 这只是返回 null。我觉得无论如何我都不应该访问它(上面写着private-),但我还是尝试了。
  • @mui/system/useTheme - 这就是我希望的工作。然而,这也可能是最奇怪的一个。它给了我默认主题,但它排除了许多属性。比如它只提供了palette.mode,除此之外palette下没有其他key。 (你可以在下面看到整个事情)
{
    "breakpoints": {
        "keys": ["xs", "sm", "md", "lg", "xl"],
        "values": { "xs": 0, "sm": 600, "md": 900, "lg": 1200, "xl": 1536 },
        "unit": "px"
    },
    "direction": "ltr",
    "components": {},
    "palette": { "mode": "light" },
    "shape": { "borderRadius": 4 }
}
  • styled-components/useTheme - 返回 undefined
  • @mui/styled-engine-sc/useTheme - 返回undefined。 (我感觉这和styled-components/useTheme是一回事。)

这些都是 VSCode 可以给我的所有建议,除了 @mui/system/useTheme@mui/system/useTheme/useTheme 之类的东西(这是同一件事)。我也尝试过谷歌搜索,但它总是很旧,比如:

如果有人知道,请问如何在 MUI 5 的组件中获取主题?

【问题讨论】:

  • @mui/material/styles/useTheme 是正确使用的。如果您没有通过@mui/material/styles/ThemeProvider 指定其他主题,它只会返回默认主题。
  • @RyanCogswell 但是,我用@mui/material/styles/ThemeProvider 指定了一个不同的... 让我更清楚地说明我的问题。我也会尝试添加一个 MRE
  • 这是一个简单的例子,显示 useTheme 工作:codesandbox.io/s/usetheme-example-bbule?file=/src/App.js
  • @RyanCogswell 我发现了问题 - 您不能在 ThemeProvider 所在的同一组件中使用 useTheme。一旦我制作了一个新组件,它就可以正常工作了。谢谢你的榜样!

标签: reactjs material-ui styled-components


【解决方案1】:

事实证明,正确的useTheme@mui/material/styles/useTheme,并且您不能在执行ThemeProvider 的同一组件中使用useTheme。例如,这个:

const App = () => {
    const theme = useTheme();
    return (
        <ThemeProvider theme={myTheme}>
            <Box bgcolor={theme.palette.background.default} width={100} height={100} />
        </ThemeProvider>
    );
};

无法正常工作。但是,这个:

const MyComponent = () => {
    const theme = useTheme();
    return <Box bgcolor={theme.palette.background.default} width={100} height={100} />;
};

const App = () => (
    <ThemeProvider theme={myTheme}>
        <MyComponent />
    </ThemeProvider>
)

可以正常工作,因为useTheme 用于单独的组件中。

【讨论】:

  • sx prop 还提供了访问主题的方法,mui.com/system/basics/#theme-getter
  • @userharis 是的,我使用 useTheme 钩子来处理无法使用 sx 属性的东西 - 这只是一个示例。
【解决方案2】:

对于仍在为此苦苦挣扎的任何人,我通过直接从@mui/material 导入createThemeThemeProvideruseTheme 使其工作...

theme.js:

import { createTheme } from '@mui/material';

export const theme = createTheme({
    ...
});

_app.tsx(我正在使用 next.js)

import { CssBaseline, ThemeProvider } from '@mui/material';
import type { AppProps } from 'next/app';
import React from 'react';

import { theme } from '../theme';

function MyApp({ Component, pageProps }: AppProps) {
    return (
        <React.StrictMode>
            <CssBaseline />
            <ThemeProvider theme={theme}>
                <Component {...pageProps} />
            </ThemeProvider>
        </React.StrictMode>
    );
}

export default MyApp;

navigation.tsx(我的 useTheme 组件)

import { Drawer, useTheme } from '@mui/material';
import React from 'react';

const Navigation = (): JSX.Element => {
    const theme = useTheme();

    const drawerSx = {
        '& .MuiDrawer-paper': {
            background: `linear-gradient(to bottom right, ${theme.palette.primary.main}, ${theme.palette.primary.dark})`,
        },
    };

    return (
        <Drawer sx={drawerSx} variant="permanent">
           ...
        </Drawer>
    );
};

export default Navigation;

在我这样做之前我一直在苦苦挣扎,它只是应用默认主题,而不是自定义主题。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 2018-09-25
    • 2019-11-09
    • 2019-07-31
    • 2021-02-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多