Search code examples
javascriptreactjsstyled-components

How do I get the state of the parent component in a child styled component using tagged template literals?


I have a react component App as following, it has a state WHRatio, and my div component will use the WHRatio value to calculate the height value. In my following way, it can work, it can get the parent component state WHRatio successfully.

import React, { useState } from "react";

export default function App() {
  const sizeWidth = 100;
  const [WHRatio, setWHRatio] = useState(1);

  const getContainerHeight = () => Math.floor(sizeWidth / WHRatio);

  const incWHRatio = () => setWHRatio(WHRatio + 1);

  return (
    <>
      <div
        style={{
          width: sizeWidth,
          height: getContainerHeight(),
          backgroundColor: "orange"
        }}
      >
      </div>
      <button onClick={incWHRatio}>Inc WHRatio</button>
    </>
  );
}

As we known, styled-components utilises tagged template literals to style the components.

// something like this
const Container = styled.div`
  background-color: orange;
  width: 100px;
  height: 200px;
`

I want to use the tagged template literals to style my component rather than the inline style. So how do I get the state of the parent component in a child styled component using tagged template literals?

Online Demo


Solution

  • You do that by passing props value to custom style, for example:

    const Container = styled.div`
      background-color: orange;
      width: 100px;
      height: ${props => props.customHeight + "px"}
    `
    

    Full Example:

    import React, { useState } from "react";
    import styled from "styled-components";
    
    const Container = styled.div`
      background-color: orange;
      width: 100px;
      height: ${props => props.customHeight + "px"}
    `
    
    export default function App() {
      const sizeWidth = 100;
      const [WHRatio, setWHRatio] = useState(1);
    
      const getContainerHeight = () => Math.floor(sizeWidth / WHRatio);
    
      const incWHRatio = () => setWHRatio(WHRatio + 1);
    
      return (
        <>
          <Container
            customHeight={getContainerHeight()} 
          ></Container>
          <button onClick={incWHRatio}>Inc WHRatio</button>
        </>
      );
    }
    

    Also, you can use css feature and pass it to styled component, for more details and examples you can check this url.

    Example 2:

    import styled, { css, keyframes } from 'styled-components'
    
    const animation = keyframes`
      0% {
        opacity: 0;
      }
    
      100 {
        opacity: 1;
      }
    `
    
    const animationRule = css`
      ${animation} 1s infinite alternate;
    `
    
    const Component = styled.div`
      animation: ${animationRule};
    `
    

    DEMO URL