Search code examples
reactjsstyled-components

Calculating additional props in styled component


I have a fairly simple styled component but I want to use the props to calculate some additional props for use in interpolations later. I realise that I could do the calculations inside the expressions but that would mean repeating them multiple times. Here is my code.

const StyledColumns = styled.div.attrs({
    columnWidths: props => calculateColumnWidths(props)
})`

    display: grid;
    grid-column-gap: 40px;
    grid-row-gap: 20px;

    grid-template-columns: ${props => props.columnWidths[0]}

    // Use props.columnWidths a few more times...

`

There are two problems here - (A) I get an error saying that upper-case characters can't be used in attribute names and (B) That's made me realise that the attributes are actually added in the DOM to the div. I thought this was just a handy way to calculate additional props.

Is there a better way of doing this so I only have to run the calculations once but nothing appears in the rendered DOM?


Solution

  • I would suggest wrapping your styled-component in a HOC to make the calculation there.

    const StylisedColumn = React.memo(props => {
      const columnWidths = calculateColumnWidths(props);
      const Column = styled.div`
        display: grid;
        grid-column-gap: 40px;
        grid-row-gap: 20px;
        grid-template-columns: ${columnWidths[0]}
    
        // Use columnWidths a few more times...
      `;
    
      return <Column {...props} />;
    });
    

    use React.memo to avoid re-renders, like pure components :)