Context Api + Hook, Dark Mode building as a useCase

March 05, 2021

Alt-Text

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';

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

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"
  }
};
  • Now it’s time to creating context: (Moment of truth).
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

  • 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>
  );
}
  • 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>
  );
}

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';
  • Importing the Context that was created in app.js

    import { ThemeContext } from "./App";
  • 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>
    </>
  );
}
  • Dark Mode Functions:

    const darkMode = () => {
    setState(theme.dark);
    };
  • Light Mode Functions:

    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:
// 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

Hope you enjoyed the use case for the useContext Hooks.

Happy Coding!


© 2021, Utkarsh Yadav . All Rights Reserved