DEV Community

Hrittik Bhattacharjee for espelar.dev

Posted on • Updated on

React Hooks by Example - Part 1

Learn Hooks = Make Money!๐Ÿค‘

Let's jump right in!
Oh wait, what are hooks?

React docs has this to say

"Hooks are a new addition in React 16.8. They let you use state and other React features without writing a class"

Honestly though, you're definitely better off learning hooks there, but in case you prefer a less bloated source in more of a go-to, no-BS spirit, read on!
Okay let's make some money!

The code for all the examples can be found at this Code Sandbox.
This is Part 1 of a three-part series, and it covers the OG hooks; useState, useEffect and useContext!๐Ÿ˜Ž


useState

  • The useState hook is used to store and update dynamic data in the application, i.e. "State".
  • Create a state variable and a function to update said state value:

    const [state, setState] = useState(initialState);
    
  • Update the value of the state variable:

    setState(newState);
    
  • Example:

    // /src/UseStateExample.js 
    
    import { useState } from "react";
    
    export default function UseStateExample() {
      const [counter, setCounter] = useState(0);
    
      return (
        <div className="UseStateExample">
          <h1>Dinero!</h1>
          <h2>You have {counter} ๐Ÿ’ต</h2>
          <button onClick={() => setCounter(counter + 1)}>Get 1 $</button>
        </div>
      );
    }
    
  • In the above example,

    • The state variable counter is initialized to 0 using the useState hook.
    • When the button is clicked, the setter function setCounter runs and increments the value of counter by 1.
  • See it in action here and the code at this sandbox!


useEffect

  • The useEffect hook takes a callback function and an optional dependency array, as arguments.
  • It is used to run some logic inside a callback function, when the value of any of the variables in a specified dependency array changes.
  • If the dependency array is empty, then the function runs once when the component is initialy loaded.
  • If you need to run some logic before the component is unmounted, this can be done by returning a function from the callback to useEffect.
  • Example:

    // /src/UseEffectExample.js
    
    import { useEffect, useState } from "react";
    
    export default function UseEffectExample() {
      const [counter, setCounter] = useState(0);
    
      useEffect(() => {
        if (counter >= 1000000) {
          alert("Congratulations! You're a Millionaire");
        }
      }, [counter]);
    
      return (
        <div className="UseEffectExample">
          <h1>Dinero!</h1>
          <h2>You have {counter} ๐Ÿ’ต</h2>
          <button onClick={() => setCounter(1000000)}>Become a Millionaire!</button>
        </div>
      );
    }
    
  • In the above example:

    • The callback to useEffect will run each time the value of counter changes.
    • When counter >= 1000000, an alert will be displayed!
  • See it in action here and the code at this sandbox!


useContext

  • React's Context API allows you to share data between components without having to prop-drill them down the hierarchy, i.e. without having to pass data down to each child component. The useContext hook allows us to do this.
  • We can create a Context in the top-level component like so:

    const CashContext = createContext("one million dollars");
    
  • And we can wrap the child components inside a Provider, and they will have access to the value:

    function App(props) {
      return (
        <CashContext.Provider value={"one million dollars"}>
          <ChildComponent1 />
        </CashContext.Provider>
      );
    }
    
  • We can then use the useContext hook inside nth level child components to access this value passed to the Provider:

    function ChildComponent1(props) {
      return (
        <div>
          <ChildComponent2 />
        </div>
      );
    }
    
    function ChildComponent2() {
      const cash = useContext(CashContext);
    
      return (
        <div>{cash}</div>
      );
    }
    
  • Note: the below example illustrates how Context can be used to access and update values from within child components, which is a pretty useful pattern.

  • Example:

    // /src/context/emojiContext.js
    
    import { createContext } from "react";
    
    export const emojis = {
      "heavy-dollar-sign": "๐Ÿ’ฒ",
      "dollar-banknote": "๐Ÿ’ต",
      "money-bag": "๐Ÿ’ฐ"
    };
    
    export const EmojiContext = createContext({
      emoji: emojis["heavy-dollar-sign"],
      setEmoji: () => {}
    });
    
    // --------------------------------------------------------
    // /src/App.js
    
    import "./styles.css";
    import { useState } from "react";
    import { BrowserRouter, Routes, Route } from "react-router-dom";
    import { emojis, EmojiContext } from "./context/emojiContext";
    import UseContextExample from "./UseContextExample";
    
    export default function App() {
      const [emoji, setEmoji] = useState(emojis["heavy-dollar-sign"]);
      const emojiValue = { emoji, setEmoji };
    
      return (
        <div className="App">
          <EmojiContext.Provider value={emojiValue}>
            <BrowserRouter>
              <Routes>
                <Route path="use-context" element={<UseContextExample />} />
              </Routes>
            </BrowserRouter>
          </EmojiContext.Provider>
        </div>
      );
    }
    
    // --------------------------------------------------------
    // /src/UseContextExample.js
    
    import { emojis, EmojiContext } from "./context/emojiContext";
    import { useContext } from "react";
    
    export default function UseContextExample() {
      const { emoji, setEmoji } = useContext(EmojiContext);
    
      const getRandom = () => {
        if (emoji === emojis["heavy-dollar-sign"]) {
          return emojis["money-bag"];
        } else {
          return emojis["heavy-dollar-sign"];
        }
      };
    
      return (
        <>
          <h1>Dinero!</h1>
          <h2>You have {emoji}</h2>
          <button onClick={() => setEmoji(getRandom())}>
            Click to get something else
          </button>
        </>
      );
    }
    
  • In the above example:

    • We create a Context in emojiContext.js and export it.
    • Import it into App.js and wrap the child components inside the Provider.
    • The "value" passed to the Provider are the state variable and setter function.
    • In UseContextExample.js we use the useContext hook to access and update the value as needed.
  • See it in action here and the code at this sandbox for emojiContext.js, App.js and UseContextExample.js!

Hope this was fun and you're sleeping on stacks of cash by now!
Stay tuned for Part 2 and 3 where we look at more hooks๐Ÿค˜
Cheers!

Top comments (2)

Collapse
 
naucode profile image
Al - Naucode

Great article, you got my follow, keep writing!

Collapse
 
the777ist profile image
Hrittik Bhattacharjee

Glad you liked it :D
Appreciate your support!