I just read in the styled-components
documentation that the following is wrong and it will affect render times. If that is the case, how can I refactor the code and use the required props to create a dynamic style?
Thank you in advance.
Tab component
import React from 'react' import styled from 'styled-components' const Tab = ({ onClick, isSelected, children }) => { const TabWrapper = styled.li` display: flex; align-items: center; justify-content: center; padding: 100px; margin: 1px; font-size: 3em; color: ${props => (isSelected ? `white` : `black`)}; background-color: ${props => (isSelected ? `black` : `#C4C4C4`)}; cursor: ${props => (isSelected ? 'default' : `pointer`)}; ` return <TabWrapper onClick={onClick}>{children}</TabWrapper> } export default Tab
To pass props to React components created with styled-components, we can interpolate functions into the string that creates the component. We create the ArrowStyled component with the styled. div tag. Then string that we pass into the tag has the rotate value set from a prop.
The css prop is a convenient way to iterate on your components without settling on fixed component boundaries yet. It works on both normal HTML tags as well as components, and supports everything any styled component supports, including adapting based on props, theming and custom components.
To pass props to React Material UI styles, we can call the useStyle hook returned by makeStyles with the props object. In makeStyles , we can set the style properties that takes the props as a parameter and return the value we want. We call makeStyles with an object that has some class names as properties.
I believe what the documentation is saying is that you should avoid including your styles inside of the rendering component:
DO THIS
const StyledWrapper = styled.div` /* ... */ ` const Wrapper = ({ message }) => { return <StyledWrapper>{message}</StyledWrapper> }
INSTEAD OF THIS
const Wrapper = ({ message }) => { // WARNING: THIS IS VERY VERY BAD AND SLOW, DO NOT DO THIS!!! const StyledWrapper = styled.div` /* ... */ ` return <StyledWrapper>{message}</StyledWrapper> }
Because what happens is when the component's Props changes, then the component will re-render and the style will regenerate. Therefore it makes sense to keep it separate.
So if you read further on to the Adapting based on props section, they explain this:
const Button = styled.button` /* Adapt the colours based on primary prop */ background: ${props => props.primary ? "palevioletred" : "white"}; color: ${props => props.primary ? "white" : "palevioletred"}; font-size: 1em; margin: 1em; padding: 0.25em 1em; border: 2px solid palevioletred; border-radius: 3px; `; // class X extends React.Component { // ... render( <div> <Button>Normal</Button> <Button primary>Primary</Button> </div> ); // }
this works because when you use the Button component in class X, it will know the props of class X without you having to tell it anything.
For your scenario, I imagine the solution would be simply:
const TabWrapper = styled.li` display: flex; align-items: center; justify-content: center; padding: 100px; margin: 1px; font-size: 3em; color: ${props => (props.isSelected ? `white` : `black`)}; background-color: ${props => (props.isSelected ? `black` : `#C4C4C4`)}; cursor: ${props => (props.isSelected ? 'default' : `pointer`)}; `; const Tab = ({ onClick, isSelected, children }) => { return <TabWrapper onClick={onClick}>{children}</TabWrapper> } const X = <Tab onClick={() => console.log('clicked')} isSelected>Some Children</Tab>
I haven't tested this at all, so please feel free to try it out and let me know if it works for you or whatever worked for you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With