停止使用样式组件传递给子项的道具

时间:2017-07-17 10:56:06

标签: javascript css reactjs styled-components

我第一次玩styled-components,而且我遇到的问题是'反应'传递道具,只有样式组件本身才使用。

这是我的组件:

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的{​​{1}}组件周围创建一个封装此道具的包装器 - 但这会有点笨拙。我确定这只是我不是这个lib的API的专业人士 - 所以有人可以指出我正确的方向吗?

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

1 个答案:

答案 0 :(得分:0)

看起来像styled-components的{​​{3}}。这不起作用的原因是因为库在应用于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
`;

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