How to use Styled Components with React
Tags: styledcomponents, react, webdev, tutorial
Published: 2023-01-04 03:40:32

Are you tired of adhering to predetermined styling concepts? Do you find yourself lost in a spaghetti plate of CSS specificity? Well, this article will teach you how to ~~stick it to the man!~~ approach styling from a components perspective, just like we do with React!

Don't get me wrong, I greatly appreciate the ease of use provided by UI libraries, not to mention the massive amount of effort that goes into creating and maintaining those libraries. The majority of these libraries even offer some way to customize the appearance of the various components they offer. But lets say you and/or your design team have a specific vision for your application that you simply cannot achieve with the available UI libraries. Let's say, for example, you make use of an AI tool to generate some ideas for your application, as I did for my capstone project at the Flatiron School. The ideas generated for you can be very dramatic and complex. If we were to try to implement these designs with an off-the-shelf UI library, straight CSS or with inline styling, we may end up adding far too much complexity to our code making it the opposite of DRY (Don't Repeat Yourself) and very difficult to maintain.

<Figure>
![Space Tourism Site Designs Generated By AI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34fw8ss7yq9kc15soy2a.png)

<figcaption align = "center">
Here's an example of AI-produced web designs for a space tourism application.
</figcaption>
</Figure>


[Styled Components](https://styled-components.com/) addresses some of these issues. However, if you don't take the time to really plan out the design of your application, you may end up in a bowl of WET (Write Everything Twice) component soup, as I did on my first attempt using Styled Components.

Alright, enough chit-chat, let's get to work.

## Installation

Installation of Styled Components is done through npm. Go ahead and install Styled Components with this:
`npm install --save styled-components`

With that out of the way, let's move on to setting up our application to make use of our future components.

## Create Global Style and Theme Components

With Styled Components we want to import global styles and a theming provider into our App component. Per the Styled Components documentation, the theme provider utilizes the context API to inject theming to all components underneath it in the component tree. This will provide us with an easy way to set our applications color scheme. Global Styles will make use of a helper function called `createGlobalStyle` to generate a special component that will control the general styling of our application. For example, we typically put body styling at the top of our CSS file. However, with Styled Components, we put body styling in the Global Styles component.

### Global Style Component

As I mentioned previously, the Global Style component will house styling for our overall application (e.g. the '*' selector, our body as well as general primitives styling). Styling for specific parts of our application, like buttons, will be implemented later in their own styled component. The way I've been doing it for months (I'm a new software developer after all...) is by adding a 'styles' directory under the 'components' directory. Go ahead and create empty Global.js and Theme.js files within the new 'styles' directory.

```bash

src
│
└───components
|   |
│   └───styles
|       |   Global.js
|       |   Theme.js
|
|   App.js
```

Open the new Global.js file now, we're going to add some basic styling here. When working with the Global Style, think about what you want all text to look like in your application. What should the spacing be like for the body class? Remember, our applications color scheme will be applied with the ThemeProvider where all of the colors will be set an actual color value (e.g. hex, rgb, hsl, etc.). So in the Global Styles file lets just set the margins and padding of our application. First, we need to import the `createGlobalStyle` helper function from styled-components. Then we can add our GlobalStyles component with whatever global styling we want inside of it.

```javascript
import { createGlobalStyle } from "styled-components";

const GlobalStyles = createGlobalStyle`
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: ${({theme}) => theme.bgColor};
  color: ${({ theme }) => theme.color};
  font-family: sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}`

export default GlobalStyles;

```

_Notice that we're making use of the Theme Provider prop to assign our various CSS colors. Cool! We'll get to that later..._

Save those changes, then open up our new Theme.js file. Here, we don't need to import anything. When we tie all of this in with our application we'll be importing the Theme Provider from styled-components into our App.js file. Instead, we'll just assign some colors here for our theming.

```javascript
const primary = "#2ECC71";
const secondary = "#333";

export const theme = {
  bgColor: secondary,
  color: primary,

  button: {
    bgColor: primary,
    color: secondary,
  },
};

```

That was pretty easy! Let's get this new stuff tied into our application.

## Setting up application-wide context

In the App component, lets add our new global style and theme components to our application.

1. We need to remove the CSS file that React imports by default, `import "./App.css"`. It will conflict with our Global Styles component, otherwise.

2. Import GlobalStyles from our Global.js file. 

3. Import the Theme Provider from the `styled-components` library.

4. Import `theme` from our `theme.js` file.

5. In the return block for App, add the `ThemeProvider` with a `theme` prop pointing to the `theme` component we imported.

6. Within the `ThemeProvider`, add the `GlobalStyles` component in a self-closing tag.

The `GlobalStyles` component is inside the `ThemeProvider` because our global styles are using values set within the `theme` component (e.g. `color: ${({theme}) => theme.primaryColor}`).

```javascript
import GlobalStyles from "./components/styles/Global";
import { ThemeProvider } from "styled-components";
import { theme } from "./components/styles/Theme";

function App() {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyles />
      <div className="App">

      {/* Application components go here */}
      
      </div>
    </ThemeProvider>
  );
}

export default App;
```

That's it! If you're using React Router, the `<BrowserRouter >...</BrowserRouter>` component is placed after (e.g. sibling-of) `<GlobalStyles />`.

## The Fun Part

Let's make a custom component now! We're going to make a custom button that will use our theme colors and it will grow a little bit when we hover over it. After we create this button, we can import into any component that will use this style of a button.

1. Back in our `src/components/styles` directory, add a new file titled `Buttons.styled.js`. I learned that by adding `styled` to the file name, we can more easily determine that styled components reside  within the file. As far as I know, it doesn’t serve any other purpose. So you could omit that part of the file name if you want, I suppose.

2. Inside Buttons.styled.js, import `styled` from `styled-components`.

3. Create a new exported component called `PrimaryButton` and assign it to ```styled.button`` ```. This assignment is what allows us to create a custom button component.

4. Inside the two backticks (` `` `) is where we’ll add our CSS styling for the button. We can also add our hover pseudo-class to handle hovering over the button.

```javascript
import styled from "styled-components";

export const PrimaryButton = styled.button`
  cursor: pointer;
  border-radius: 0;
  border: none;
  font-size: 2em;
  margin: 0.5em;
  padding: 0.5em 1em;
  background-color: ${({ theme }) => theme.button.bgColor};
  color: ${({ theme }) => theme.button.color};

  &:hover {
    opacity: 0.9;
    transform: scale(1.02);
  }
`;
```

Let's go back to `App.js` and add our styled button. 

```javascript
import GlobalStyles from "./components/styles/Global";
import { ThemeProvider } from "styled-components";
import { theme } from "./components/styles/Theme";

// 👇 Import our new styled component
import { PrimaryButton } from "./components/styles/Buttons.styled";

function App() {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyles />
      <div className="App">

        {/* 👇 Add an instance of our new button here */}
        <PrimaryButton onClick={console.log("You clicked me!")}>
          Submit!
        </PrimaryButton>
      </div>
    </ThemeProvider>
  );
}

export default App;
```

There we go! We've successfully created our first styled component.

<Figure>
![Styled Button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k3rz5k5q98pr5cgcva6u.gif)

<figcaption align = "center">
Take a look at that button! That's pretty neat!
</figcaption>
</Figure>

## Conclusion

Styled Components is a great tool to have in your toolbelt. As long as you make an appropriate amount of effort to really plan out your reusable components, Styled Components may can help make use of one of Reacts strongest appeals, the use of reusable components.

_Photo by rovenimages.com: https://www.pexels.com/photo/yellow-bokeh-photo-949587/_