DEV Community

Cover image for Context API + Hooks : Building minimalist Dark Mode
Utkarsh Yadav
Utkarsh Yadav

Posted on

Context API + Hooks : Building minimalist Dark Mode

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.

import React, { useContext } from 'react';
Enter fullscreen mode Exit fullscreen mode

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

  • 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.

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

export default function Children() {
  return (
    <div>
      <Colorify /> // passing children Component
    </div>
  );
}
Enter fullscreen mode Exit fullscreen mode

Setting up App.js (Creating Context).

  • Import children component Children.js.
  • Making themes Object.
const themes = {
  light: {
    foreground: "#000",
    background: "#fff"
  },
  dark: {
    foreground: "#fff",
    background: "#000"
  }
};
Enter fullscreen mode Exit fullscreen mode
  • Now it's time to creating context: (Moment of truth).
export const ThemeContext = React.createContext(themes);
Enter fullscreen mode Exit fullscreen mode

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

  • 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.

export default function App() {
  return (
    <ThemeContext.Provider value={themes}> // wrapper Component
      <Children />  // children Component (Props will be passed and accessed to it.)
    </ThemeContext.Provider>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • The Complete Code for App.js is below:
// 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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.
import React, { useContext, useState } from 'react';
Enter fullscreen mode Exit fullscreen mode
  • Importing the Context that was created in app.js
import { ThemeContext } from "./App";
Enter fullscreen mode Exit fullscreen mode
  • Writing Logic for Dark Mode:
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>
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode
  • Dark Mode Functions:
 const darkMode = () => {
    setState(theme.dark);
  };
Enter fullscreen mode Exit fullscreen mode
  • Light Mode Functions:
 const lightMode = () => {
    setState(theme.light);
  };
Enter fullscreen mode Exit fullscreen mode

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:
// 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>
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

Check out the preview on codesandbox and play along

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

Top comments (0)