避免使用 Styled Components 和 Typescript 传递 props
Avoid passing down props using Styled Components and Typescript
我在 React 应用程序中有以下样式化组件,它按预期工作:
const BaseButton = styled(Button)<{ borderColor: string }>`
border-color: ${({ borderColor }): string => borderColor};
`;
但是它会在控制台中生成此警告消息:
React does not recognize the borderColor
prop on a DOM element. If
you intentionally want it to appear in the DOM as a custom attribute,
spell it as lowercase bordercolor
instead. If you accidentally
passed it from a parent component, remove it from the DOM element.
为了避免这种情况,我尝试实施 documentation
中提出的解决方案
文档示例:
import styled from 'styled-components'
import Header, { Props as HeaderProps } from './Header'
const Title =
styled <
{ isActive: boolean } >
(({ isActive, ...rest }) => <Header {...rest} />)`
color: ${props => (
props.isActive ? props.theme.primaryColor : props.theme.secondaryColor
)}
`
我的原始代码按照示例重写:
const BaseButton = styled <
{ borderColor: string } >
(({ borderColor, ...rest }) => <Button {...rest} />)`
border-color: ${({ borderColor }): string => borderColor};
`;
但我收到以下错误消息:
Parsing error: '>' expected
错误指的是<Button {rest...} />
这是我的 .babelrc
配置,以防出现问题:
{
"presets": ["@babel/env", "@babel/typescript", "@babel/preset-react"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"@babel/transform-runtime",
"@babel/plugin-transform-modules-commonjs"
]
}
您现有的代码已经是正确的,但 React 给了您两个选择:
1) 使用比蛇形小写
2) 从 DOM 中删除属性(您采用了这种方法)
从代码中我可以看出您需要道具 borderColor
,但在自定义样式中,您将道具分开了
({borderColor,... rest}) => <Button {...rest} />
您删除了边框 Color 道具,但您尝试在下一行访问样式道具。
如果您希望警告消失或忽略警告,请尝试将道具重命名为 bordercolor
。
Use Transient props
TL;DR just prefix your attriibute with $
sign. example $borderColor
, $black
, $any
, $attribute
.
如果你想阻止本应由样式组件使用的道具被传递到底层 React 节点或渲染到 DOM 元素,你可以在道具名称前加上美元符号 ($) ,把它变成一个瞬态道具。
// typescript example
const BaseButton = styled(Button)<{ $borderColor: string }>`
border-color: ${({ $borderColor }): string => $borderColor};
`;
// js
const BaseButton = styled(Button)`
border-color: ${({$borderColor}) => $borderColor}
`;
// usage
<BaseButton $borderColor="red">Button</BaseButton>
第二种方法
const Comp = styled('div').withConfig({
shouldForwardProp: (prop, defaultValidatorFn) =>
!['hidden'].includes(prop)
&& defaultValidatorFn(prop),
}).attrs({ className: 'foo' })`
color: red;
&.foo {
text-decoration: underline;
}
`;
render(
<Comp hidden draggable="true">
Drag Me!
</Comp>
);
我在 React 应用程序中有以下样式化组件,它按预期工作:
const BaseButton = styled(Button)<{ borderColor: string }>`
border-color: ${({ borderColor }): string => borderColor};
`;
但是它会在控制台中生成此警告消息:
React does not recognize the
borderColor
prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercasebordercolor
instead. If you accidentally passed it from a parent component, remove it from the DOM element.
为了避免这种情况,我尝试实施 documentation
中提出的解决方案文档示例:
import styled from 'styled-components'
import Header, { Props as HeaderProps } from './Header'
const Title =
styled <
{ isActive: boolean } >
(({ isActive, ...rest }) => <Header {...rest} />)`
color: ${props => (
props.isActive ? props.theme.primaryColor : props.theme.secondaryColor
)}
`
我的原始代码按照示例重写:
const BaseButton = styled <
{ borderColor: string } >
(({ borderColor, ...rest }) => <Button {...rest} />)`
border-color: ${({ borderColor }): string => borderColor};
`;
但我收到以下错误消息:
Parsing error: '>' expected
错误指的是<Button {rest...} />
这是我的 .babelrc
配置,以防出现问题:
{
"presets": ["@babel/env", "@babel/typescript", "@babel/preset-react"],
"plugins": [
"@babel/plugin-proposal-object-rest-spread",
"@babel/transform-runtime",
"@babel/plugin-transform-modules-commonjs"
]
}
您现有的代码已经是正确的,但 React 给了您两个选择:
1) 使用比蛇形小写
2) 从 DOM 中删除属性(您采用了这种方法)
从代码中我可以看出您需要道具 borderColor
,但在自定义样式中,您将道具分开了
({borderColor,... rest}) => <Button {...rest} />
您删除了边框 Color 道具,但您尝试在下一行访问样式道具。
如果您希望警告消失或忽略警告,请尝试将道具重命名为 bordercolor
。
Use Transient props
TL;DR just prefix your attriibute with
$
sign. example$borderColor
,$black
,$any
,$attribute
.
如果你想阻止本应由样式组件使用的道具被传递到底层 React 节点或渲染到 DOM 元素,你可以在道具名称前加上美元符号 ($) ,把它变成一个瞬态道具。
// typescript example
const BaseButton = styled(Button)<{ $borderColor: string }>`
border-color: ${({ $borderColor }): string => $borderColor};
`;
// js
const BaseButton = styled(Button)`
border-color: ${({$borderColor}) => $borderColor}
`;
// usage
<BaseButton $borderColor="red">Button</BaseButton>
第二种方法
const Comp = styled('div').withConfig({
shouldForwardProp: (prop, defaultValidatorFn) =>
!['hidden'].includes(prop)
&& defaultValidatorFn(prop),
}).attrs({ className: 'foo' })`
color: red;
&.foo {
text-decoration: underline;
}
`;
render(
<Comp hidden draggable="true">
Drag Me!
</Comp>
);