How to use styled components in react

What is styled components ?

Basically styled components is a react library that helps you to write CSS inside the component.
Some advantages of styled components are :

  • It can be hard to know whether a class name is used somewhere in your code-base. styled-components makes it obvious, as every bit of styling is tied to a specific component. If the component is unused (which tooling can detect) and gets deleted, all its styles get deleted with it
  • Adapting the styling of a component based on its props or a global theme is simple and intuitive without having to manually manage dozens of classes.
  • You don’t have to hunt across different files to find the styling affecting your component, so maintenance is a piece of cake no matter how big your code-base is.

Installation

npm install –save styled-components

Use

I am using create-react-app to start a react application and below is my folder structure

This is my App.js

    import React from 'react';
    import Home from "./components/Home/Home.component"
    import "./App.css"
    function App() {
      return <Home /> 
    }

    export default App;

Lets create the home component.

import React from 'react'
import "./style.css"

export default function Home() {
     return (
          <div className="wrapper">
              <h1>Header text</h1>
              <div className="input-wrapper">
                  <input type="text" className="input" placeholader="Enter some text..." />
              </div>
              <div className="button-wrapper">
                  <button className="btn primary">Primary</btn>
                  <button className="btn secondary">Secondary</btn>
              </div>
          </div>
         )}

style.css

.wrapper {
     display: flex;
     flex-direction: column;
     align-items: center;
}
.button-wrapper {
     display : flex;
     min-width: 350px;
     justify-content: space-between;
     margin: 2rem;
}
.btn {
     min-width: 150px;
     padding:  1rem;
     color: white;
     border: none
}
.primary {
     background-color: green;
}
.secondary {
     background-color: red;
}
.input {
     padding: 1rem;
     border-radius: 10px;
     border:1px solid #ccc;
}

This is how it looks on the browser.

Lets use styled-components in our project. First create a folder named styled-components inside components and create a file named HeaderText.js within it.

import styled from "styled-components"
export default styled.h1`
font-size : 40px;
`

Lets use our styled component in our home component

import React from 'react'
import "./style.css"
import HeaderText from "../styled-components/HeaderText"

export default function Home(){
      return (
          <div className="wrapper">
            <HeaderText>Header text</HeaderText>
            ...
          </div>
      )
}

The result is still same.You can change the font size to see the difference

Now lets create another component called Input.js inside styled-components

import styled from "styled-components"
export default styled.input.attrs(props => ({
    type: props.type ? props.type : 'text',
    placeholder: props.placeholder
}))`
    padding: 1rem;
    border-radius: 10px;
    border: 1px solid #ccc;
`

Lets use our Input styled component in our home component

import React from 'react'
import "./style.css"
import HeaderText from "../styled-components/HeaderText"
import Input "../styled-components/Input"

export default function Home(){
      return (
          <div className="wrapper">
            <HeaderText>Header text</HeaderText>
            <Input type="text" placeholder="Enter some text ..."/>
            ...
          </div>
      )
}

Now lets create a component called FlexWrapper.js inside styled-components for a flex container

import styled from "styled-components"
export default styled.div`
    display : flex;
    justify-content: ${props => props.jc};
    align-items: ${props => props.at};
    min-width: ${props => props.mw ? props.mw : '100%'};
    margin: ${props => props.margin ? props.margin: 0};
    flex-direction: ${props => props.direction ? props.direction: 'row'};
`

Now our home component wil be

import React from 'react'
import "./style.css"
import HeaderText from "../styled-components/HeaderText"
import Input "../styled-components/Input"
import FlexWrapper "../styled-components/Input"

export default function Home(){
      return (
          <FlexWrapper direction="column" at="center">
            <HeaderText>Header text</HeaderText>
            <Input type="text" placeholder="Enter some text ..."/>
            <FlexWrapper direction="column" at="center">
              ...
            </FlexWrapper>
          </FlexWrapper>
      )
}

Finally let’s create a styled component for our button as Button.js

import styled from "styled-components"
export default styled.button.attrs`
    min-width: ${props => props.mw ? props.mw : '100%'};
    padding: ${props => props.padding? props.padding: 0};
    color: white;
    border: none;
    background-color: ${props => props.type === "primary" ? "green" : props.type === "secondary" && "red"};
`

Let’s use our button component inside home component but this time with a different approach i.e object spreading and object destructuring.As we used styled component , we dont need style.css

import React from 'react'
import HeaderText from "../styled-components/HeaderText"
import Input "../styled-components/Input"
import FlexWrapper "../styled-components/Input"
import Button"../styled-components/Button"

const bt = {
   mw: "150px",
   padding: "1rem"
};

const button = {
    primary : {
       ...bt,
       type : "primary"
    },
    secondary: {
       ...bt,
       type : "secondary"
    }
}

export default function Home(){
      const { primary, secondary } = button;
      return (
          <FlexWrapper direction="column" at="center">
            <HeaderText>Header text</HeaderText>
            <Input type="text" placeholder="Enter some text ..."/>
            <FlexWrapper direction="column" at="center">
               <Button {...primary}>Primary</Button>
               <Button {...secondary}>Secondary</Button>
            </FlexWrapper>
          </FlexWrapper>
      )
}

We can use ThemeProvider for theming purpose.ThemeProvider simply injects theme(a object) into all styled components anywhere beneath it in the component tree.

import React from 'react'
import { ThemeProvider } from 'styled-components'
import HeaderText from "../styled-components/HeaderText"
import Input "../styled-components/Input"
import FlexWrapper "../styled-components/Input"
import Button"../styled-components/Button"

const bt = {
   mw: "150px",
   padding: "1rem"
};

const button = {
    primary : {
       ...bt,
       type : "primary"
    },
    secondary: {
       ...bt,
       type : "secondary"
    }
}

export default function Home(){
      const { primary, secondary } = button;
      return (
        <ThemeProvider theme={{ color: '#DB7093' }}>
          <FlexWrapper direction="column" at="center">
            <HeaderText>Header text</HeaderText>
            <Input type="text" placeholder="Enter some text ..."/>
            <FlexWrapper direction="column" at="center">
               <Button {...primary}>Primary</Button>
               <Button {...secondary}>Secondary</Button>
            </FlexWrapper>
          </FlexWrapper>
        </ThemeProvider>
      )
}

Now let’s use theme to change color of our header text

import styled from "styled-components"
export default styled.h1`
font-size : 40px;
color : ${props => props.theme.color};
`

The final result will be

You can also find about State Management in react without redux

Thank You