typescript - 如何使用 Material UI 和 TypeScript 将自定义道具传递给样式化组件?
问题描述
我正在使用 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 模块的情况下摆脱这种情况,需要styled
从 Material UI 中使用?
这也是另一个类似的问题。
我想将媒体查询添加到样式化组件中,它说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.
...
解决方案
只是我的2美分,希望我提供的解决方案可以帮助你。
主要原因是material-ui版本,你的项目可能会混淆版本4和版本5。
第一:安装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-uistyled-engine
指向emotion
,所以我们需要重写 webpack 配置来引用 styled-components。
官方文档解释了如何在 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
第三:覆盖 webpack 配置
- 创造
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',
}),
);
4th: 现在你可以使用带有 styled-components 的 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 提供了一个临时的 props -$
避免自定义的 props 传递给 DOM。
https://styled-components.com/docs/api#transient-props
一个演示 git repo供您参考和交叉检查,以防您无法使其工作
推荐阅读
- sql-server - 如何获取存储过程返回的值并将其用于 INSERT INTO... SELECT... 语句
- android - 如何检查monkeyrunner是否发生崩溃
- reactjs - Gatsby.js 和 redux-promise 中间件
- javascript - 使用 $cleanName 有效但 $cleanComment 无效
- git - git pull 自动强制更新,不做改动
- heroku - Ubuntu 16.04 上的 Heroku 登录错误
- angular - HTTP 服务器推送 Angular 模块
- yii2 - 在 Yii2 DatePicker 小部件中隐藏历史下拉选择值
- python - Scipy 的 distance.cdist 函数只是单线程还是可以使其成为多线程?
- sql-server - 我应该为 64 位重建 SQL Server 应用程序吗?