我第一次玩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
)。
答案 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
`;
我现在接受这个作为答案,但如果有任何其他方法不能创建这样的包装器组件/功能,我将接受另一个答案。