我有一个扩展第三方组件的样式组件:
import Resizable from 're-resizable';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
flex: 0 0 ${(props) => props.someProp}px;
`;
const PaneContainer = ({ children, someProp }) => (
<StyledPaneContainer
someProp={someProp}
>
{children}
</StyledPaneContainer>
);
export default PaneContainer;
这导致浏览器控制台出现以下错误:
警告:React无法识别DOM上的
someProp
道具 元件。如果您有意希望它作为自定义出现在DOM中 属性,拼写为小写someProp
。如果你 意外地从父组件传递它,从DOM中删除它 元件
因此,我将道具更改为data-*
属性名称:
import Resizable from 're-resizable';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
flex: 0 0 ${(props) => props['data-s']}px;
`;
const PaneContainer = ({ children, someProp }) => (
<StyledPaneContainer
data-s={someProp}
>
{children}
</StyledPaneContainer>
);
export default PaneContainer;
这很有效,但我想知道是否有一种原生方式在样式化组件中使用道具而不将它们传递给DOM元素(?)
答案 0 :(得分:20)
通过release 5.1.0,您可以使用瞬态道具。这样,您不需要额外的包装程序,即减少了不必要的代码:
临时道具是一种传递道具的新模式,道具仅由样式化组件显式使用,而无意传递给更深的组件层。使用方法如下:
const Comp = styled.div`
color: ${props => props.$fg || 'black'};
`;
render(<Comp $fg="red">I'm red!</Comp>);
请注意道具上的美元符号($)前缀;这标记为暂时的,样式化组件不知道将其添加到呈现的DOM元素中,也不将其进一步传递到组件层次结构中。
样式化的组件:
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
flex: 0 0 ${(props) => props.$someProp}px;
`;
父组件:
const PaneContainer = ({ children, someProp }) => (
<StyledPaneContainer
$someProp={someProp} // '$' signals the transient prop
>
{children}
</StyledPaneContainer>
);
答案 1 :(得分:9)
根据vdanchenkov this styled-components github issue的建议,您可以对道具进行细分,并仅将相关的道具传递给Resizable
const ResizableSC = styled(({ someProp, ...rest }) => <Resizable {...rest} />)`
flex: 0 0 ${(props) => props.someProp}px;
`;
答案 2 :(得分:2)
对于那些由于SC和react-router的Link
问题而降落在这里的人(如我):
const StyledLink = styled(({ isCurrent, ...rest }) => <Link {...rest} />)(
({ isCurrent }) => ({
borderBottomColor: isCurrent ? 'green' : 'transparent',
}),
)
答案 3 :(得分:-1)
您可以尝试 defaultProps :
import Resizable from 're-resizable';
import PropTypes from 'prop-types';
...
const ResizableSC = styled(Resizable)``;
export const StyledPaneContainer = ResizableSC.extend`
flex: 0 0 ${(props) => props.someProp}px;
`;
StyledPaneContainer.defaultProps = { someProp: 1 }
const PaneContainer = ({ children }) => (
<StyledPaneContainer>
{children}
</StyledPaneContainer>
);
export default PaneContainer;
我们也可以使用' attrs '传递道具。这有助于附加额外的道具(示例取自样式组件官方文档):
const Input = styled.input.attrs({
// we can define static props
type: 'password',
// or we can define dynamic ones
margin: props => props.size || '1em',
padding: props => props.size || '1em'
})`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed props */
margin: ${props => props.margin};
padding: ${props => props.padding};
`;
render(
<div>
<Input placeholder="A small text input" size="1em" />
<br />
<Input placeholder="A bigger text input" size="2em" />
</div>
);