避免使用样式化组件和打字稿传递道具

rfc*_*484 2 typescript reactjs babeljs styled-components

我在 React 应用程序中有以下样式组件,可以按预期工作:

const BaseButton = styled(Button)<{ borderColor: string }>`
  border-color: ${({ borderColor }): string => borderColor};
`;
Run Code Online (Sandbox Code Playgroud)

但是它会在控制台中生成此警告消息:

React 无法识别borderColorDOM 元素上的prop。如果您有意希望它作为自定义属性出现在 DOM 中,请将其拼写为小写bordercolor。如果您不小心从父组件传递了它,请将其从 DOM 元素中删除。

为了避免这种情况,我尝试实施文档中提出的解决方案

文档示例:

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
)}
`
Run Code Online (Sandbox Code Playgroud)

我的原始代码按照示例重写:

const BaseButton = styled <
{ borderColor: string } >
(({ borderColor, ...rest }) => <Button {...rest} />)`
  border-color: ${({ borderColor }): string => borderColor};
`;
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误消息:

解析错误:“>”预期

错误是指 <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"
  ]
}
Run Code Online (Sandbox Code Playgroud)

Ank*_*mar 8

使用瞬态道具

TL;DR 只是在你的属性前面加上$符号。例如$borderColor, $black, $any, $attribute

如果您想防止样式化组件使用的 props 传递到底层 React 节点或渲染到 DOM 元素,您可以在 prop 名称前加上美元符号 ($),将其转换为瞬态 prop。

// typescript example
const BaseButton = styled(Button)<{ $borderColor: string }>`
    border-color: ${({ $borderColor }): string => $borderColor};
`;

Run Code Online (Sandbox Code Playgroud)
// js
const BaseButton = styled(Button)`
    border-color: ${({$borderColor}) => $borderColor}
`;
Run Code Online (Sandbox Code Playgroud)
// usage
<BaseButton $borderColor="red">Button</BaseButton>

Run Code Online (Sandbox Code Playgroud)

方法二

结帐 shouldForwardProp

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>
);
Run Code Online (Sandbox Code Playgroud)

  • 很高兴了解瞬态道具!再次感谢 Ankit,这实际上应该被标记为正确的答案,因为它与样式组件更相关,而不是反应本身...... (2认同)

Kar*_*k R 2

您现有的代码已经是正确的,但反应给了您两个选择:

1)使用小写字母而不是蛇形字母

2)从DOM中删除属性(你采用了这种方法)

从代码中我可以看到您需要 prop borderColor,但在自定义样式中,您将 props 分开

({borderColor,... rest}) => <Button {...rest} />

您删除了 border Color 道具,但尝试在样式道具中访问下一行。

bordercolor相反,如果您希望警告消失或只是忽略警告,请尝试将道具重命名为。