如何使用 Material UI 和 TypeScript 将自定义道具传递给样式化组件?
Posted
技术标签:
【中文标题】如何使用 Material UI 和 TypeScript 将自定义道具传递给样式化组件?【英文标题】:How to pass custom props to styled components using Material UI and TypeScript? 【发布时间】:2021-09-11 06:45:04 【问题描述】:我正在使用 TypeScript(v4.2.3) 和 Material UI(v4.11.3),并尝试将自定义道具传递给 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 模块的情况下摆脱这种情况,需要使用 Material UI 中的styled
?
这也是另一个类似的问题。
我想向样式化组件添加媒体查询,上面写着TypeError: Cannot read property 'addRule' of null
。
const PrintableTableContainer = styled(TableContainer)(() => (
'@media print':
'@page': size: 'landscape' ,
,
));
我也试过了。
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.
...
【问题讨论】:
无法摆脱这个? 【参考方案1】:只需我的 2 美分,希望我提供的解决方案可以帮助到您。
主要原因是material-ui版本,你的项目可能会混淆版本4和版本5。
1st:安装material-ui v5
@next
版本 = v5
安装 material-ui 和 styled-engine 以使用 styled-components
// 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 中使用 styled-components:
对于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
3rd:覆盖 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',
),
);
第 4 点:现在您可以将 material-ui 与 styled-components 一起使用
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 props - $
来避免自定义 props 传递给 DOM。
https://styled-components.com/docs/api#transient-props
demo git repo 供您参考和交叉检查,以防您无法使其工作
【讨论】:
提前致谢!其实我没有意识到Material UI有新版本5。我会试一试。 尝试了所有步骤,还尝试了 mui/examples repo 中的示例,警告不会消失。但是这个答案***.com/questions/49613774/… 确实为我解决了这个问题以上是关于如何使用 Material UI 和 TypeScript 将自定义道具传递给样式化组件?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 material-ui 主题中导入和使用自定义字体?
如何在 Material-UI 中使用 Box 组件覆盖按钮?
如何覆盖(覆盖)material-ui(React)中的类和样式
ReactJS + Material-UI:如何使用 Material-UI 的 <DatePicker> 将当前日期设置为默认值?