我在代码的某些部分有这样的内容:

import React from 'react'
import styled from 'styled-components'

type PropsType = {
  direction?: 'horizontal' | 'vertical'
  flex?: number | string
  width?: number | string
  minWidth?: number | string
  height?: number | string
  minHeight?: number | string
  fill?: string
  padding?: number | string
  paddingTop?: string | number
  paddingRight?: string | number
  paddingBottom?: string | number
  paddingLeft?: string | number
}

const Box = styled.div<PropsType>`
  display: flex;
  ${({ padding }) =>
    padding &&
    `padding: ${typeof padding === 'number' ? `${padding}px` : padding};`}
  ${({ width }) =>
    width && `width: ${typeof width === 'number' ? `${width}px` : width};`}
  ${({ minWidth }) =>
    minWidth &&
    `min-width: ${typeof minWidth === 'number' ? `${minWidth}px` : minWidth};`}
  ${({ height }) =>
    height && `height: ${typeof height === 'number' ? `${height}px` : height};`}
  ${({ minHeight }) =>
    minHeight &&
    `min-height: ${
      typeof minHeight === 'number' ? `${minHeight}px` : minHeight
    };`}
  ${({ flex }) => flex && `flex: ${flex};`}
  ${({ fill }) => fill && `background-color: ${fill};`}
  ${({ direction }) =>
    direction &&
    `flex-direction: ${direction === 'horizontal' ? 'row' : 'column'};`}
  ${({ paddingTop }) =>
    paddingTop &&
    `padding-top: ${
      typeof paddingTop === 'number' ? `${paddingTop}px` : paddingTop
    };`}
  ${({ paddingRight }) =>
    paddingRight &&
    `padding-right: ${
      typeof paddingRight === 'number' ? `${paddingRight}px` : paddingRight
    };`}
  ${({ paddingBottom }) =>
    paddingBottom &&
    `padding-bottom: ${
      typeof paddingBottom === 'number' ? `${paddingBottom}px` : paddingBottom
    };`}
  ${({ paddingLeft }) =>
    paddingLeft &&
    `padding-left: ${
      typeof paddingLeft === 'number' ? `${paddingLeft}px` : paddingLeft
    };`}
`

export default Box

然后我有了这个:

export default function Page() {

  return (
    <>
      <Box padding={24} width="100%">
        <h1>(tab)</h1>
      </Box>
      <Box fill={COLOR.white} paddingTop={24} paddingBottom={24}>
        (Text)
      </Box>
      <Box padding={24}>
        (Output)
      </Box>
    </>
  )
}

相关部分是fill属性和其他属性,它们显示在DOM中:

enter image description here

这是正常行为吗?或者如何将其从DOM中删除?

我使用的是Next.js,默认为next.config.js,其中tsconfig.json:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "types": ["node"],
    "baseUrl": "."
  },
  "include": ["next-env.d.ts", "index.d.ts", "**/*.ts", "**/*.tsx"],
  "exclude": ["node_modules"],
  "ts-node": {
    "compilerOptions": {
      "module": "commonjs"
    }
  }
}

推荐答案

事实上,我们通常预期styled-componentssmart enoughnot pass个额外的props ,用于样式化的基本HTML标记(在本例中为div):

如果样式化的目标是一个简单的元素(例如styled.div),[...]Style-Components[足够智能,可以自动为您过滤非标准属性.

不幸的是,在本例中,"足够聪明"是not enough:fill属性是standard for SVG elements,因此styled-components让它通过...


一个非常简单的解决方法是使用transient prop.它包括在props 前面加上一个美元符号:

如果希望防止将样式组件使用的props 传递给底层的Reaction node 或呈现给DOM元素,则可以在props 名称前面加上美元符号($),从而将其转换为临时props .

const Box2 = styled.div<{ $fill?: string; }>`
  ${({ $fill }) => $fill && `background-color: ${$fill};`}
`;

<Box2 $fill="yellow">Content...</Box2>

不幸的是,这意味着稍微更改您的内部API.


另一种解决方法是使用shouldForwardProp配置.有了这一点,我们可以精确地指定应该通过什么或不应该通过什么:

未通过测试的props 不会传递给底层组件,就像临时props 一样.

const Box3 = styled.div.withConfig({
  shouldForwardProp(prop, isValidProp) {
    return (prop as string) !== "fill" && isValidProp(prop);
  }
})<{ fill?: string; }>`
  ${({ fill }) => fill && `background-color: ${fill};`}
`;

<Box3 fill="yellow">Content...</Box3>

演示:https://codesandbox.io/s/wispy-silence-mp54zv?file=/src/App.tsx


关于styled-components内置"智能"过滤器的更多解释:如上所述,一旦props 是any个HTML标准元素的标准属性(就像本例中的fill是SVG的标准属性),它就被列入白名单,并被传递.

这是因为styled-components实际上依赖于@emotion/is-prop-valid,为了简单起见,它将过滤器实现为单个公共白名单,而不是每个HTML标准标记都有一个列表.

我们可以找到白名单中的fill属性here.

Javascript相关问答推荐

如何使用JavaScript用等效的功能性HTML替换标记URL格式?

根据总价格对航班优惠数组进行排序并检索前五个结果- Angular HTTP请求

窗口.getComputedStyle()在MutationObserver中不起作用

Bootstrap动态选项卡在切换选项卡后保持活动状态,导致元素堆叠

未捕获错误:在注销后重定向到/login页面时找不到匹配的路由

在这种情况下,如何 for each 元素添加id?

函数返回与输入对象具有相同键的对象

在我的html表单中的用户输入没有被传送到我的google表单中

数字时钟在JavaScript中不动态更新

实现JS代码更改CSS元素

使用GraphQL查询Uniswap的ETH价格

我怎么才能得到Kotlin的密文?

当使用';字母而不是与';var#39;一起使用时,访问窗口为什么返回未定义的?

类构造函数不能在没有用With Router包装的情况下调用

为什么云存储中的文件不能公开使用?

Node.js错误: node 不可单击或不是元素

如何在Java脚本中并行运行for或任意循环的每次迭代

如何设置时间选取器的起始值,仅当它获得焦点时?

不允许在对象文本中注释掉的属性

使用JavaScript或PHP从div ID值创建锚标记和链接