typescript - 如何使用 Material UI 和 TypeScript 将自定义 Prop 传递给样式化组件?

标签 typescript material-ui styled-components

我正在使用 TypeScript(v4.2.3) 和 Material UI(v4.11.3),并尝试将自定义 Prop 传递给 styled成分。

import React from 'react';
import {
  IconButton,
  styled,
} from '@material-ui/core';

const NavListButton = styled(IconButton)(
 ({ theme, panelOpen }: { theme: Theme; panelOpen: boolean }) => ({
   display: 'inline-block',
   width: 48,
   height: 48,
   borderRadius: 24,
   margin: theme.spacing(1),
   backgroundColor: panelOpen ? theme.palette.secondary.dark : 'transparent',
 }),
);

...

const Component: React.FC<Props> = () => {
  return (
    <NavListButton panelOpen={true} />
  );
};

这工作正常,但如果我检查控制台,它会遇到错误。
Warning: React does not recognize the `panelOpen` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `panelopen` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
    at button
    at ButtonBase ...
如何在不使用 styled-components 模块的情况下摆脱这种情况,需要使用 styled从 Material 用户界面?
这也是另一个类似的问题。
我想向样式组件添加媒体查询,它说 TypeError: Cannot read property 'addRule' of null .
const PrintableTableContainer = styled(TableContainer)(() => ({
  '@media print': {
    '@page': { size: 'landscape' },
  },
}));
enter image description here
我也试过这个。
const PrintableTableContainer = styled(TableContainer)`
  @media print {
    @page { size: landscape }
  }
`;
但它也说
Argument of type 'TemplateStringsArray' is not assignable to parameter of type 'CreateCSSProperties<(value: string, index: number, array: readonly string[]) => unknown> | ((props: { theme: Theme; } & ((value: string, index: number, array: readonly string[]) => unknown)) => CreateCSSProperties<...>)'.
  Type 'TemplateStringsArray' is not assignable to type 'CreateCSSProperties<(value: string, index: number, array: readonly string[]) => unknown>'.
    Types of property 'filter' are incompatible.
...

最佳答案

只是我的 2 美分,希望我提供的解决方案可以帮助您。
主要原因是 material-ui 版本,您的项目可能会与版本 4 和版本 5 混淆。
第一:安装 material-ui v5

  • @next版本 = v5
  • 安装 material-ui 和 styled-engine 以使用 styled-component
  • // npm
    npm install @material-ui/core@next @material-ui/styled-engine-sc@next styled-components
    npm install --save-dev @types/styled-components
    
    
    // yarn 
    yarn add @material-ui/core@next @material-ui/styled-engine-sc@next styled-components
    yarn add --dev @types/styled-components
    

    第二:安装 react-app-rewired
    默认 Material -ui styled-engine指向 emotion ,所以我们需要覆盖 webpack 配置来引用 styled-components。
    Official Doc解释了如何在 material-ui 中使用样式组件:
    对于 create-react-app , 安装 react-app-rewired
    // npm 
    npm install --save-dev react-app-rewired customize-cra
    
    // yarn
    yarn add --dev react-app-rewired customize-cra
    

    第三:覆盖 webpack 配置
    官方示例:https://github.com/mui-org/material-ui/tree/next/examples/create-react-app-with-styled-components-typescript
  • 创建 config-overrides.js
  • 覆盖 styled-engine 路径以指向 styled-engine-sc 路径

  • // config-overrides.js
    const { addWebpackAlias, override } = require('customize-cra');
    
    module.exports = override(
      addWebpackAlias({
        '@material-ui/styled-engine': '@material-ui/styled-engine-sc',
      }),
    );
    

    第四:现在你可以使用带有样式组件的 material-ui
    import { IconButton, styled, TableContainer, Theme } from "@material-ui/core";
    
    const NavListButton = styled(IconButton)(
      ({ theme, $panelOpen }: { theme?: Theme, $panelOpen: boolean }) => ({
        display: "inline-block",
        width: 48,
        height: 48,
        borderRadius: 24,
        margin: theme?.spacing(1),
        backgroundColor: $panelOpen ? theme?.palette.secondary.dark : "transparent"
      })
    );
    
    const PrintableTableContainer = styled(TableContainer)(() => ({
      "@media print": {
        "@page": { size: "landscape" }
      }
    }));
    
    ...
    
    <NavListButton $panelOpen={true} />
    <PrintableTableContainer />
    
    
    对于第一个问题,React does not recognize the `panelOpen` prop on a DOM element. .
    styled-components 提供了一个 transient Prop - $ 避免将自定义 Prop 传递给 DOM。
    https://styled-components.com/docs/api#transient-props

    demo git repo供您引用和交叉检查,以防万一您无法使用

    关于typescript - 如何使用 Material UI 和 TypeScript 将自定义 Prop 传递给样式化组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68172215/

    相关文章:

    javascript - 修改 React 样式对象似乎会破坏 dom 样式

    reactjs - 根据配置条目在 React 中动态导入组件

    javascript - 允许 Material UI RaisingButton 标签中存在变量

    javascript - 将鼠标悬停在没有包装器的样式组件上

    javascript - 样式组件未将样式应用于自定义功能 react 组件

    reactjs - 在 freeSolo 模式下使用带有 react-hook-form 的 Material UI 自动完成功能

    javascript - Meteor 中的异常处理

    使用 vscode 在 .js 文件上 typescript

    javascript - 为什么我不能扩展快速请求类型?

    reactjs - React Material UI 主题更改