Context API + Hooks : Building minimalist Dark Mode
Tags: react, webdev, javascript, codenewbie
Published: 2021-03-05 15:25:09

# Why this hook ?

The react application (Complex), data is passed in top-down approach (Parent-to-children components) and this made the manual passing of props more complicated. The props for (Example: UI Theme, Local Preferences) become "cumbersome". So Facebook engineers made some efforts to save us. (Developed another Hook).

# What is `useContext()` hooks ?

Context provides a way to pass data through the component tree without having to pass props down manually at every level.

```js
import React, { useContext } from 'react';
```

# When to use ?

Context is designed to share data that can be considered “global” for a tree of React components, such as the current authenticated user, theme, or preferred language.

# One of the use Case: (Making UI Theme) 🌗

we will be learning `Context` in different steps below:

- Setting up `Children.js` (passing props to child component).
- Setting up `App.js` (creating Context).
- Setting up `Colorify.js` (tweaking UI themes from child).

## Setting up `Children.js`.

- Make a `Colorify.js` file, which will later contain buttons and some logic to toggle from dark Mode and Light Mode.
- Now make a new component file named `Children.js`, which will **act as a parent for his Child Component `Colorify.js`**

> see the below diagram to understand the flow of data.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qtlp4e8gai6losft78ew.png)

- The main gotcha is that... The props will be passed to `children.js` component and will be accessed down the REACT DOM component i.e to its child components. 

> Note: more the children, all of them can have access to the props passed to `children.js`. 

```js
import React from "react";
import Colorify from "./Colorify";

export default function Children() {
  return (
    <div>
      <Colorify /> // passing children Component
    </div>
  );
}
```
## Setting up `App.js` (Creating Context).

- Import children  component `Children.js`.
- Making `themes` Object.

```json
const themes = {
  light: {
    foreground: "#000",
    background: "#fff"
  },
  dark: {
    foreground: "#fff",
    background: "#000"
  }
};
```
- Now it's time to creating context: (Moment of truth).

```js
export const ThemeContext = React.createContext(themes);
``` 
This line of code means, we are exporting the initialized Context created as `ThemeContext` and passing the `themes` props(value) as an argument.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tec3jdygay4bai4ohn9.png)

- Inside functional Component, passer a wrapper component `<ThemeContext.Provider>` which has a `value prop` pass the theme object as the value prop.

- And inside the wrapper component pass the `children` Component where the props need to pass.

- This complete piece of code means that ... **You are passing object `themes` as the default value to prop, that is passed to child component in React DOM Hierarchy**.

```js
export default function App() {
  return (
    <ThemeContext.Provider value={themes}> // wrapper Component
      <Children />  // children Component (Props will be passed and accessed to it.)
    </ThemeContext.Provider>
  );
}
```
- The Complete Code for **App.js** is below:
```js
// Complete app.js code

import "./styles.css";
import React from "react";
import Children from "./Children";

const themes = {
  light: {
    foreground: "#000",
    background: "#fff"
  },
  dark: {
    foreground: "#fff",
    background: "#000"
  }
};

export const ThemeContext = React.createContext(themes);

export default function App() {
  return (
    <ThemeContext.Provider value={themes}> // wrapper Component
      <Children />  // children Component (Props will be passed and accessed to it.)
    </ThemeContext.Provider>
  );
}
```
## Setting up `Colorify.js` Component (Final Logic)
- The final logic for changing UI Theme from `dark` to `light` and `forth`.
- Start by importing **useContext** and **useState**.

```js
import React, { useContext, useState } from 'react';
```
- Importing the `Context` that was created in `app.js`
```js
import { ThemeContext } from "./App";
```
- Writing Logic for **Dark Mode**: 
```js
export default function Colorify() {
  const theme = useContext(ThemeContext);
  const [state, setState] = useState(theme.light);
  const darkMode = () => {
    setState(theme.dark);
  };
  const lightMode = () => {
    setState(theme.light);
  };
  return (
    <>
      <div
        style={{
          backgroundColor: state.background,
          color: state.foreground,
          height: 100,
          width: 200,
          margin: 100,
          border: `1px solid ${state.foreground}`
        }}
      ></div>
      <button onClick={darkMode}>Dark Mode!</button>
      <button onClick={lightMode}>Light Mode!</button>
    </>
  );
}
```
- Dark Mode Functions: 
```js
 const darkMode = () => {
    setState(theme.dark);
  };
``` 
- Light Mode Functions: 
```js
 const lightMode = () => {
    setState(theme.light);
  };
```

we are just changing state from `theme.dark` to `theme.light`
and setting the background color of the Component as `state.foreground` **for text color** and `state.background` **for background color**.

- The Complete Code for `Colorify.js` is: 

```js
// Complete Code for Colorify.js

import React, { useContext, useState } from "react";
import { ThemeContext } from "./App";

export default function Colorify() {
  const theme = useContext(ThemeContext);
  const [state, setState] = useState(theme.light);
  const darkMode = () => {
    setState(theme.dark);
  };
  const lightMode = () => {
    setState(theme.light);
  };
  return (
    <>
      <div
        style={{
          backgroundColor: state.background,
          color: state.foreground,
          height: 100,
          width: 200,
          margin: 100,
          border: `1px solid ${state.foreground}`
        }}
      ></div>
      <button onClick={darkMode}>Dark Mode!</button>
      <button onClick={lightMode}>Light Mode!</button>
    </>
  );
}

```
### Check out the preview on codesandbox and play along

{% codesandbox crimson-hill-mztwi %}

Hope you enjoyed the use case for the `useContext` Hooks.
Please Do comment!
Happy Coding!