【问题标题】:How to use Material UI from component library in a project with Material UI already?如何在已有 Material UI 的项目中使用组件库中的 Material UI?
【发布时间】:2021-08-23 16:58:25
【问题描述】:

我在我的项目中使用 Material UI,同时,我们有一个组件库(一个包含许多共享 React 组件的 npm 包)。

库中的这些组件也是基于 Material UI。

因此,当我从库中导入这些组件以在我的项目中使用时,它会将 <styles> 块复制到正在使用的某个组件(例如 MuiButtonBase-root)。

基于此,当第二个 MuiButtonBase-root 出现时,它会重置一些 css 样式。

有解决办法吗?


编辑 1:

这是一个示例,可能组件不是按此顺序排列的,因为我不确定问题发生的顺序。

// myProject
import { AppBar, Tabs, Tab, ThemeProvider } from '@material-ui/core';
import { Button, SharedComponentProvider } from '@shared-components'; // components based on MUI

function App() {
  return (
    <SharedComponentProvider>
      <ThemeProvider theme={fooTheme}>
        <AppBar position="static">
          <Tabs>
            <Tab label="Item One"  />
            <Tab label="Item Two"  />
            <Tab label="Item Three"  />
          </Tabs>
        </AppBar>

        <Button>Click me</Button>
      </ThemeProvider>
    </SharedComponentProvider>
  );
}

SharedComponentProvider 是这样的:

import { StylesProvider, createGenerateClassName } from '@material-ui/core/styles';
const generateClassName = createGenerateClassName({
  seed: 'shared-components',
});

function SharedComponentProvider({ children }: any) {
  return (
    <ThemeProvider theme={sharedTheme}>
      { children }
    </ThemeProvider>
  );
}

由于Tab组件也是基于MUI的Button组件,所以会创建两个&lt;style&gt;标签,里面有. MuiButtonBase-root,这样就可以结束了。

【问题讨论】:

  • 你能分享一些代码 sn-ps 以便更容易理解这个问题吗?您使用的是 Next.js、CRA 还是 Gatsby?你在用ThemeProvider吗?
  • 当然,我会的
  • @NirmalyaGhosh,已更新
  • 您是否在应用程序中导入ThemeProvider
  • @NirmalyaGhosh 是的,我再次更新了它,提供了有关提供商的更多详细信息

标签: reactjs material-ui


【解决方案1】:

今晚我在 MUI 5.x 中遇到了同样的问题。并通过一个名为ThemeInheritor 的小型库组件解决了它。

import React from "react";
import { Theme, ThemeProvider} from "@mui/material/styles";

export interface ThemeInheritorProps  {
  theme: Theme;
  children: React.ReactNode
};

export default function ThemeInheritor({ theme, children }: ThemeInheritorProps) {
  return (
      <ThemeProvider theme={theme}>
          {children}
      </ThemeProvider>
  );
}

它只是获取应用程序的主题并将其提供给库“世界”。

将此组件导出到您的应用程序后,应将其集成到应用程序头部的主题化过程中,如下所示:

import { ThemeInheritor } from "YOURLIBRARY";

...

<StyledEngineProvider injectFirst>
  <ThemeProvider theme={muiTheme}>
    <ThemeInheritor theme={muiTheme}>
    ...
    </ThemeInheritor>
  </ThemeProvider>
</StyledEngineProvider>

其中muiThemecreateTheme() 函数创建的主题。

ThemeInheritor 为树中使用的所有库组件提供托管应用程序的主题。

【讨论】:

    【解决方案2】:

    您可以在项目中更改用于生成的 CSS 的前缀以避免冲突:https://material-ui.com/styles/api/#creategenerateclassname-options-class-name-generator

    【讨论】:

    • 我之前尝试过这个解决方案,但我无法在我的项目的根目录中添加StyleProvider,因为它也会更改不是从shared-components 导入的组件的className。有没有办法解决这个问题?
    • 在您的问题中,您提到您正在从@material-ui/core@shared-components 导入组件。为什么不从@shared-components 导入和导出@material-ui/core 组件呢?这样,您将在一个地方使用StyleProvider
    【解决方案3】:

    您正在从 @shared-components 包中导出 ButtonSharedComponentProvider 组件。您还需要从 @shared-components 包中导出 ThemeProvider

    这是因为在您的 @shared-components 包中,您正在使用 Material UI 的 ThemeProvider 包装您的组件。您需要在主应用程序中重用相同的提供程序。

    import { AppBar, Tabs, Tab, ThemeProvider } from '@shared-components';
    

    【讨论】:

      猜你喜欢
      • 2018-09-25
      • 2020-04-07
      • 1970-01-01
      • 2016-04-28
      • 2021-01-06
      • 2021-01-02
      • 2019-06-19
      • 2019-06-03
      • 2022-10-17
      相关资源
      最近更新 更多