Context/Provider Pattern
Tags: react, designpatterns, design, webdev
Published: 2023-11-18 16:54:59

The Provider Pattern is a technique in React that uses the Context API to efficiently share and manage global state or data across multiple components without the need for manual prop passing. It simplifies data sharing in deeply nested component structures.

Let's walk through the Provider Pattern in React with step-by-step explanation.

**Problem:**

Imagine you have a deeply nested component structure, and you need to pass some shared data (like user authentication state or theme) to a component deep down the hierarchy. Passing this data through props at each level can become cumbersome and this problem is called Prop Drilling.

> To avoid prop drilling we can use Provider pattern

**Step 1: Problem Code - Prop Drilling:**

```jsx
// Top-level component
function App() {
  const user = { id: 1, name: 'John Doe', isAuthenticated: true };
  return <NavBar user={user} />;
}

// Intermediate component
function NavBar({ user }) {
  return <UserProfile user={user} />;
}

// Deeply nested component
function UserProfile({ user }) {
  // Access user data here
  return <div>{user.name}</div>;
}
```

As the application grows, adding more components in between would require passing the `user` prop through each level, even if those intermediate components don't use the `user` prop.

**Step 2: Solution - Using Provider Pattern:**

Let's introduce the Provider Pattern using React Context API to avoid prop drilling.

```jsx
import React, { createContext, useContext } from 'react';

// Create a context
const UserContext = createContext();

// Provider component to wrap around App
function UserProvider({ children }) {
  const user = { id: 1, name: 'John Doe', isAuthenticated: true };
  
  return (
    <UserContext.Provider value={user}>
      {children}
    </UserContext.Provider>
  );
}

// Intermediate component - No need to pass user prop
function NavBar() {
  return <UserProfile />;
}

// Deeply nested component - Can access user data directly
function UserProfile() {
  const user = useContext(UserContext);
  return <div>{user.name}</div>;
}

// Wrap the top-level component with the provider
function App() {
  return (
    <UserProvider>
      <NavBar />
    </UserProvider>
  );
}
```

**Step-by-Step Explanation:**

1. **Create a Context:**
   - `const UserContext = createContext();` creates a context to share user data.

2. **Provider Component:**
   - `UserProvider` component wraps the top-level component (`App`) and provides the `user` data through the context using `UserContext.Provider`.

3. **Intermediate Component:**
   - `NavBar` component doesn't need to receive `user` as a prop. It can directly access user data using the `useContext` hook.

4. **Deeply Nested Component:**
   - `UserProfile` component can access the `user` data directly using the `useContext(UserContext)` hook.

5. **Wrap Top-Level Component:**
   - Finally, wrap the top-level component (`App`) with `UserProvider` to make the user data available throughout the component tree.

Using the Provider Pattern with React Context helps avoid prop drilling and makes it easier to share global state or data across multiple components. It's especially useful for scenarios where many components need access to the same data.

> "Your feedback and ideas are invaluable – drop a comment, and let's make this even better!"

😍 If you enjoy the content, please 👍 like, 🔄 share, and 👣 follow for more updates!
Join me on a professional journey through my LinkedIn profile: [Linkedin Profile](https://www.linkedin.com/in/kurmivivek295/)