Unlocking React's Hidden Gems: A Beginner's Guide to useContext and createContext

·

4 min read

Unlocking React's Hidden Gems: A Beginner's Guide to useContext and createContext

Are you a budding React developer looking to take your skills to the next level? Do you find yourself struggling with prop drilling and complex state management in your React applications? If so, you've come to the right place.

Before diving into the useContext hook in React, there are two key concepts you should understand, which will make grasping the concept easier.

Concept 1: Object Destructuring

One way to access values within an object is by object destructuring. Suppose you have an object like this:

const person = { name: "afaq", age: 19 };

You can extract values like this:

const { name, age } = person;

Remember, the spelling of keys must match for successful restructuring

Concept 2: Dynamic Children Values in React Components

Imagine you want to create a reusable button component, but you don't want the button text to be the same every time. To achieve this, you can create a component for the button:

function MyButton({ children }) {
  return <button>{children}</button>;
}

By using the children prop, you can customize the button text when using the component.

Understanding the Need for useContext

To understand a new concept, it's crucial to know why you need it. Let's consider an example:

Suppose you have a state called "name" in one component:

const [name, setName] = useState("afaq");

Now, you want to use this state in another component. If it's just one or two components, you can pass it as a prop. But in larger projects with many components, passing props becomes impractical.

Introducing the useContext Hook

This is where the useContext hook in React comes to the rescue. It uses the concept of passing state like we did with props but extends it to the entire React app, making the state accessible in any component.

Using createContext and useContext

Here's how to use createContext and useContext:

// In your main file (e.g., index.js)
import React, { createContext, useContext } from "react";

const MyContext = createContext();

function App() {
  const name = "afaq"; // Replace with your state
  return (
    <MyContext.Provider value={name}>
      {/* Your app's components */}
    </MyContext.Provider>
  );
}

// In any component where you need the value
import React, {  useContext } from "react";

function MyComponent() {

  const name = useContext(MyContext);

  return (
   <h1>My name is {name}</h1>
}

By wrapping your app's components with MyContext.Provider, you can access the value anywhere using useContext.

Taking It Further: Organizing Your Context

In real-world projects, you'll have multiple states and functions. To keep things tidy, create a separate file, e.g., Context.jsx, to define your context:

// Context.jsx
import React, { createContext, useContext } from "react";

export const MyContext = createContext();

export function MyContextProvider({ children }) {
  const name = "afaq"; // Replace with your 
  return (
    <MyContext.Provider value={name}>
      {children}
    </MyContext.Provider>
  );
}

// In your main file (e.g., index.js)
import {  MyContext } from "./Context";

function App() {

const { name } = useContext(MyContext)
  return (
    <>
      <h1>My name is {name} </h1>
    </>
  );
}

Now, you can organize your context and make it easily accessible across your app.

Being practical : Passing useState in the Context Value

Consider a scenario where you have a state variable count

const [count, setCount] = useState(0);

You want to share this count value with other components. To do this, you can pass it in the context value:

// In your context file (e.g., Context.jsx)
import React, { createContext, useContext, useState } from "react";

const CountContext = createContext();

export function CountProvider({ children }) {
  const [count, setCount] = useState(0);

  return (
    <CountContext.Provider value={{ count, setCount }}> 
      {children}
    </CountContext.Provider>
  );
}

Here, we wrap our count state and its setCount function in the context provider.

Note: When passing multiple values make sure to use double curly brackets {{ count, setCount }} like this, as you can see in the above code otherwise you will not be able get these values in your component because Javascript won't know that you are passing set of objects to it.

Using count in Other Components

Now, in any component where you want to access and modify the count state, you can use useContext to retrieve it:

// In a component where you want to use 'count'
import React, { useContext } from "react";
import { CountContext } from "./Context"; // Import your context

function CountDisplay() {
  const { count , setCount} = useContext(CountContext); // Access 'count' from the context

return (
   <>
     <div>Count: {count}</div>;
     <button onClick={() => setCount(count + 1)}>Increment Count</button>
   </>
)
}

Here, we import the CountContext and use useContext to access the count state and the setCount function. You can now use them in your components as needed.

Conclusion:

Now you've learned how to share and manage state using useState and useContext. This powerful combination allows you to centralize state management and easily share it across different parts of your React application.

Feel free to ask if you have any questions or need further clarification. Happy coding!