Context API

Context API

Without Context API, we have to do prop-drilling. Meaning, props will have to be passed down from one Component into another (sometimes, through multiple intermediate Components in between)

See https://github.com/explorer436/programming-playground/tree/main/front-end-development-playground/react-playground/10-ContextAPI

What is a Provider in React?

In React, a Provider typically refers to a component that utilizes the Context API to make data accessible to a subtree of components without having to explicitly pass props down through every level.

Context API

React’s Context API is a way to share data that can be considered “global” for a tree of React components. This avoids “prop drilling,” where you have to pass props through multiple intermediate components that don’t directly use the data, just to get it to a deeply nested child.

createContext

  1. You begin by creating a Context object using React.createContext().
  2. This object comes with two components: Provider and Consumer.
  3. useContext hook is now the preferred way to consume context.

The Provider Component

  1. The Provider component is a part of the Context object (MyContext.Provider if you created MyContext).
  2. It is rendered higher up in the component tree, wrapping the components that need access to the shared data.
  3. It accepts a value prop, which is the data you want to make available to its descendants. This value can be anything: a string, number, object, array, or even functions.

How it Works

  1. Any component nested within the Provider’s subtree can then “consume” the value provided by the Provider.
  2. This consumption is typically done using the useContext hook, which takes the Context object as an argument and returns the current context value.

In essence, a Provider acts as a central hub for sharing specific data or state within a defined part of your React application, simplifying state management and making your code cleaner.

All components need to be rendered within the Providers

If someone is trying to render things from outside of the Provider, we run into problems.

We have to make sure that all Components are rendered within the Providers.

e.g.

This is problematic.

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import MenuItem from "./MenuItem";

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <MenuItem category="size" />
          <MenuItem category="quantity" />
        </header>
      </div>
    );
  }
}

export default App;

This is the fix.

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";
import MenuItem from "./MenuItem";
import {Provider} from './Provider'
import Store from './Store'

class App extends Component {
  render() {
    return (
      <Provider value={new Store()}>
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <MenuItem category="size" />
            <MenuItem category="quantity" />
          </header>
        </div>
      </Provider>
    );
  }
}

export default App;

If you have multiple providers, this is what it would look like:

import React from "react"
import ReactDOM from "react-dom/client"
import App from "./App"
import { Browser Router } from "react-router"
import "beercss"
import "material-dynamic-colors"
import { FileProvider } from "./hooks/fileContext"
import { FileSystemProvider } from "./hooks/fileSystemContext"
import { SnackProvider } from "./hooks/snackBarContext"
import { AppProvider} from "./hooks/appContext"
import { MsalProvider } from "@azure/msal-react"
import { msalConfig } from "./authConfig"
import { PublicClientApplication } from "@azure/msal-browser"
import "./index.css"

const msalInstance = new PublicClientApplication (msalConfig)

// Ensure MSAL is initialized before rendering the app
msalInstance
  .initialize()
  .then(() => {
    const root = ReactDOM.createRoot(document.getElementById("root"))
    root.render(
      <MsalProvider instance={msalInstance}>
        <SnackProvider>
          <BrowserRouter>
            <FileSystemProvider>
              <FileProvider>
                <AppProvider>
                  <App/>
                </AppProvider>
              </FileProvider>
            </FileSystemProvider>
          </BrowserRouter>
        </SnackProvider>
      <MsalProvider>,
    )
  })
  .catch((error) => {
    console.error(`${"Error initializing MSAL:"} ${error}`)
  })

Links to this note