No Fuss Dark-Mode Toggle with React & Styled-Components! 🌞↔️🌖
Tags: webdev, tutorial, react, javascript
Published: 2021-08-18 05:32:36

Have you noticed **dark mode** is pretty standard lately? 

Well, that's because it's badass!

Let's achieve this new standard of awesome by utilizing styled-components and React! 

It's super easy to implement, so let's get straight to it! 💯

---
## Resources 

###👉 [Demo](https://styled-components-darkmode.netlify.app/)
###👉 [Repo](https://github.com/chansen17/styled-components-darkmode)

---
## Some things I'm expecting you to know
1. Development Environment
2. Basics in React
3. Basic S(C)ass

---
## 1. Fresh React project
Let's clean up the file structure ~ *if you want.* I deleted all unnecessary files for this project. Removing `App.css` and all testing related files. Be sure to remove necessary lines of code in `index.js`. I also cleaned up the boilerplate between the `header` tags.

--- 
## 2. Install and Import styled-components
With a fresh project, let's now install and import styled-components. 
- `yarn add styled-components` or
- `npm install --save styled-components`

Let's now import styled-components like so:
```
import styled from 'styled-components'`
```

---
## 3. Let's create a simple landing page with styled-components

In our `App()` let's return a `Page`, `Container`, `Heading`, `H1`, `P`, `Toggle`, and `ThemeImage` component, respectively. It should look like so
![Example code showing the Page, Heading, H1, P, Toggle, and ThemeImage components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0dvrh7tpi1vtvfp2lp5f.png)

---

## 4. Now that we have our layout, let's create each of our components
`Page` and `Container`
![Page and Container component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0p4lz4gcacptj0ptwy7f.png)
`Heading` and `H1`
![Heading and H1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6io3xddrn3oypq22rjog.png)
`P` and `Toggle`
![P and Toggle components](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fog9wx0oy7z4o9ko5ah2.png)
`ThemeImage` is the component that will contain our toggle state images 
![ThemeImage component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lokti6hl65uhkz6gd65n.png)

---

## 5. Let's create state for our toggle component
In order for us to to toggle between light and dark mode, we need to hold state. Let's begin by importing the useState hook. `import {useState} from 'react'`. Then add it to your `App()` component like so:
```javascript 
const [isDarkMode, setDarkMode] = useState(false);
```
Next let's add the logic that will toggle between light and dark mode for our button `Toggle` component. 
```javascript
const handleToggle = () => {
   setDarkMode(!isDarkMode);
   // console.log(isDarkMode);
}
```
This functions only responsibility is to toggle the opposite of what the current state is. In other words, if the state is currently `true`, toggling it will become `false`. If `false` it becomes `true`. 

---

## 6. Update our `Toggle` component
Now that we have a function that can toggle our light ~ dark state, let's update our `Toggle` component like so:
```javascript
<Toggle onClick={handleToggle}></Toggle>
```

---

## 7. Import images to display the active theme
If we want to show our users the current and next theme, we can do so visually with the use of a Moon and Sun image. Let's import the images at the top of our code like so:

*images are available in the repo*
```javascript 
import Moon from './images/moon.png';
import Sun from './images/sun.png';
```
Then lets update our `ThemeImage` component like so:
```javascript
<Toggle onClick={handleToggle}>
   <ThemeImage src={ !isDarkMode ? `${Sun}` : `${Moon}` } />
</Toggle>
```
Here we are updating the `ThemeImage` components src attribute as it is an instance of `img`. We are also conditionally setting the image with a simple ternary operator while also utilizing template literals. 
I'll explain with some pseudocode. You can read this like `if stateIsNotDarkMode ? render Moon : else render Sun.`

---

## 8. Let's update some style properties in our components
We're almost done! Let's update the `background` and `color` properties in a few of our components 

First, Let's change the `Page` components background style to: 
```css
background: ${props => props.light ? "#eee" : "#333"};
```
Secondly, let's change the `H1` components color style to: 
```css
color: ${props => !props.light ? "papayawhip" : "#000"};
```
Lastly, let's change the  `P` components color styles to: 
```css
color: ${props => !props.light ? "#eee" : "#333"};
```
Here we are conditionally styling our background or color properties based on the prop that we pass into our components. If the component contains the `light` prop, render this color, else render this color.

---

## 9. Pass in our default Theme to our components with the `light` prop
All we have to do now is update our components in the layout with the default `light` prop. Like so:
```javascript
  return (
    <Page light={!isDarkMode ? true : false}>
      <Container>
        <Heading>
          <H1 light={!isDarkMode ? true : false}>Dynamic Styling with Styled-Components</H1>
          <P light={!isDarkMode ? true : false}>Lorem ipsum dolor sit amet consectetur adipisicing elit. Dicta error natus at vitae sint qui sapiente impedit rerum commodi fugit ullam repudiandae itaque, saepe fuga facere temporibus excepturi dolore officia?</P>
          <Toggle light={!isDarkMode ? true : false}  onClick={handleToggle}>
            <ThemeImage src={ !isDarkMode ? `${Moon}` : `${Sun}` } />
          </Toggle>
        </Heading>
      </Container>
    </Page>
  );
}
```
Here I am also conditionally rendering the `light` prop to either be true, or false, depending on on our state. 

---

## Conclusion! 👏
Congrats! That's a wrap on **No Fuss Dark-Mode Toggle with React & Styled-Components!** Hopefully, if everything went right, you were able to implement a badass dark mode into your project, in 9 simple steps! 

Please don't hesitate to hit me up on [Twitter](https://twitter.com/hyggedev) in regards to any questions, concerns or if you just wanna say hello! 

---

## Are you a beginner web developer!? 
{% link https://dev.to/hyggedev/how-to-stay-focused-as-a-self-taught-frontend-web-developer-7gp %}
{% link https://dev.to/hyggedev/how-to-build-a-responsive-react-navigation-menu-with-styled-components-3682 %}
{% link https://dev.to/hyggedev/easiest-way-to-add-icons-to-your-react-apps-5cgd %}