Search code examples
reactjsmaterial-uistyled-componentsreact-props

Passing props using less text


I've recently started using Styled Components, I can see what the fuss is about but there are some things that I'm either not understanding properly or are just not DRY at all. Take this example where I create a Card component, and I'm using the Material UI scheme at the same time:

import React from 'react'
import styled from 'styled-components/macro'
import Grid from '@material-ui/core/Grid'

const S_Card = styled(Grid)`
    background-color: rgb(191, 161, 228);
    box-sizing: border-box;
    height: ${props => props.height};
    margin: ${props => props.marg}; 
    margin-left: ${props => props.margleft};
    margin-right: ${props => props.margright};
    margin-top: ${props => props.margtop};
    margin-bottom: ${props => props.margbottom};
    padding: ${props => props.pad}; 
    padding-left: ${props => props.padleft};
    padding-right: ${props => props.padright};
    padding-top: ${props => props.padtop};
    padding-bottom: ${props => props.padbottom};
`

export default function Card(props) {
const p = props

return(

    <S_Card 
        container
        item
        xs = {p.xs} 
        md = {p.md}
        alignItems = {p.alignItems}
        justify = {p.justify}
        height = {p.height}
        pad = {p.pad}
        padleft = {p.padleft}
        padright = {p.padright}
        padtop = {p.padtop}
        padbottom = {p.padbottom}
        marg = {p.marg}
        margleft = {p.margleft}
        margright = {p.margright}
        margtop = {p.margtop}
        margbottom = {p.margbottom}
    >
        {p.children}
    </S_Card>

    )
}

Let's say in this case I'm going to call this component from somewhere else typing this:

<Card xs = {4} height = '100px' padleft = '10px' padright = '10px' margtop = '20px' margbottom = '20px />'

I think the problem is pretty obvious here. Way too many lines just to set up something as simple as paddings and margins.

Do I have to declare all these props in order to pass them through to the style wrapper const S_Card = styled(Grid)` ?

It seems like such a big amount of lines to be repeated for a lot of components (most components are going to have to pass through margins, paddings, etc, which means a lot of lines). So I assume I'm not doing this the right way, how do I improve this, please?


Solution

  • You can use the Spread syntax (...) to clean up the code instead of deconstructing each prop individually:

    export default function Card(props) {
    
    return(
    
        <S_Card 
            container
            item
            {...props}
        />
    
        )
    }
    

    The spread notation will also take care of rendering the children, so I was comfortable removing it as well.