The docs for styled-components show its default styled export accepts a single argument:
styled- This is the default export. This is a low-level factory we use to create the
styled.tagnamehelper methods.- Arguments
component/tagname- Description
- Either a valid react component or a tagname like
'div'.
I've emphasized "valid react component" here because they explicitly aren't saying this has to be a React component created by styled, although traditionally that is how this is used (as well as documented under their Extending Styled section). An example of this is shown below:
const RedBox = styled.div`
border: 1px solid black;
color: red;
`;
// Traditionally, the argument you pass to `styled` is
// a react element *created by a previous `styled` call*
const BlueBox = styled(RedBox)`
color: blue;
`;
function Example() {
return (
<div>
<RedBox>I am a red box</RedBox>
<BlueBox>I am a blue box</BlueBox>
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-is.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/styled-components.js"></script>
<div id="root"></div>
Nothing unsurprising with the above.
However, my question is what if you pass a non styled component as the argument to the styled call? Shouldn't that returned element also get the styles applied?
Consider the following simple example:
// Create two simple components, one functional, one class-based
const BoxFunctional = (props) => <div>{props.children}</div>;
class BoxClass extends React.Component {
render() {
return <div>{this.props.children}</div>
}
}
// Here, I pass a functional React Component to `styled`
const RedBoxFunctional = styled(BoxFunctional)`
color: red;
border: 1px solid black;
`;
// Again, passing another regular React component, this time a class component
const RedBoxClass = styled(BoxClass)`
color: red;
border: 1px solid black;
`;
function Example() {
return (
<div>
<p>The below two Boxes are regular react elements:</p>
<BoxFunctional>I am a functional box</BoxFunctional>
<BoxClass>I am a class box</BoxClass>
<hr />
<p>The below two boxes <em>should</em> be styled:</p>
<RedBoxFunctional>I am a functional red box</RedBoxFunctional>
<RedBoxClass>I am a class red box</RedBoxClass>
</div>
);
}
ReactDOM.render(<Example />, document.getElementById('root'));
<script src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-is.production.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/styled-components.js"></script>
<div id="root"></div>
Running the above snippet you can see that the styled components are not styled, despite them extending a "valid" react component.
Is there something I'm missing? Are the docs just incorrect? Can styled only apply styles to an existing react component that is made by a previous styled call?
