2

我是styled-components第一次玩,我遇到了“react”传递仅由样式组件本身使用的道具的问题。

这是我的组件:

import { Link } from 'react-router-dom';

const CtaButton = styled(Link)`
  background: ${props => props.primary ? 'red' : 'yellow'}
  color: white;
  display: inline-block;
  padding: 0.5em 1em;
`;

当我使用primary道具调用它时,我收到一条警告,react表明我正在将primary道具应用于<a />元素。我明白为什么会发生这种情况 - 但我该如何阻止它呢?

我当然可以围绕react-router'sLink组件创建一个包装器来剥离这个道具——但这有点笨拙。我敢肯定,只是我还不是这个库 API 的专业人士——所以有人能指出我正确的方向吗?

styled.a出于某种原因,当我直接创建 DOM 组件时(例如),我没有这个问题。

4

1 回答 1

3

看起来这是一个已知styled-components的限制。这不起作用的原因是因为库在应用于 DOM 元素时会剥离道具(基于白名单)。对于组件,这实际上不能以同样的方式完成,因为随机组件实际上并没有可预测的 API。

虽然作者和贡献者正在解决这个问题,但这是我想出的解决方法:

import React from 'react';
import { Link } from 'react-router-dom';

const StyledLink = ({ primary, ...rest }) => <Link {...rest} />;

export const CtaButton = styled(StyledLink)`
  background: ${props => props.primary ? 'red' : 'yellow'}
  color: white;
  display: inline-block;
  padding: 0.5em 1em;
`;

换句话说,用另一个组件包装该组件,该组件剥离任何样式组件特定的道具,然后重新应用剩余的道具。它并不漂亮,但据我所知,这是最简单的解决方案。

您还可以创建一个 HOC 来为您执行此操作:

const withStrippedProps = propsToRemove => TargetComponent => (props) => {
  const strippedProps = Object.entries(props)
    .filter(([key]) => !propsToRemove.includes(key))
    .reduce((stripped, [key, value]) => ({ ...stripped, [key]: value }), {});
  return <TargetComponent {...strippedProps} />
};

const StyledLink = withoutProps(['primary'])(Link);
const CtaButton = styled(StyledLink)`
  // css goes here
`;

我现在接受这个作为答案,但如果有任何其他方法不能创建这样的包装组件/函数,我将愿意接受另一个答案。

于 2017-07-17T11:53:41.103 回答