Context API - anastasiamexa/react-complete-guide-course-resources GitHub Wiki

The Context API in React is a feature that allows you to share values like props between components without explicitly passing them through each level of the component tree. It's particularly useful when you have data that needs to be accessible to many components at different levels of nesting.

Basics of Context API:

1. Context Object:
At the core of the Context API is the createContext function. This function creates a context object that has two components: Provider and Consumer.

2. Provider:
The Provider component is used to wrap the components that need access to the context. It takes a value prop, which is the data you want to share.

const MyContext = React.createContext();

const MyComponent = () => {
  return (
    <MyContext.Provider value={/* some data */}>
      {/* Components that can access the context */}
    </MyContext.Provider>
  );
};

3. Consumer:
To access the context, you use the Consumer component. It's a function as a child component that receives the current context value.

<MyContext.Consumer>
  {value => /* render something based on the context value */}
</MyContext.Consumer>

When to use Context:

  • Prop Drilling:
    Use Context API when you find yourself passing props through many levels of components, and it becomes cumbersome.
  • Global State:
    When you have global state that needs to be accessed by multiple components, but doesn't warrant using a state management library like Redux.
  • Theming:
    For theming or other scenarios where you have shared configuration that affects the styling or behavior of components.

Pros of using Context:

  • Simplifies Prop Drilling:
    It eliminates the need to pass props through intermediate components that don't use the data but are required to pass it down.
  • Global State Management:
    Provides a simple way to manage global state without resorting to more complex state management solutions like Redux.
  • Cleaner Code:
    Helps in writing cleaner and more maintainable code by reducing the clutter of passing down props.
  • Easy to Use:
    Once set up, it's relatively easy to use and reduces the boilerplate code compared to manually passing props.
  • Promotes Separation of Concerns:
    Encourages a clear separation of concerns by allowing components to focus on their own responsibilities rather than passing data around.

useContext (React 16.3 and later):

In recent React versions (16.3 and later), you can also use the useContext hook to consume context, which provides a more concise syntax for functional components.

Here's an example of how you can use useContext:

import React, { useContext } from 'react';

// Creating a context
const MyContext = React.createContext();

// Providing the context at a higher level
const App = () => {
  const data = /* some data */;

  return (
    <MyContext.Provider value={data}>
      <ChildComponent />
    </MyContext.Provider>
  );
};

// Consuming the context in a functional component using useContext
const ChildComponent = () => {
  const value = useContext(MyContext);

  return <div>{value}</div>;
};

Using useContext makes the code more readable and eliminates the need for the Consumer component. It also allows you to consume the context directly inside the functional component without wrapping it in a separate component.

Keep in mind that useContext is only available in functional components, so if you are working with class components or need to consume context in lifecycle methods, the Consumer component is still a viable option. However, for most modern React applications and functional components, useContext is the preferred approach.

Example:

This example demonstrates how to use the React Context API to manage and share the theme across components in a React application. Let's break down the files:

1. App.jsx:

  • This is the entry point of your application.
  • It wraps the main content of the application inside a ThemeContextProvider, which provides the theme information to its children.
import Page from './Page';
import ThemeContextProvider from './ThemeContextProvider';

function App() {
  return (
    <ThemeContextProvider>
      <Page />
    </ThemeContextProvider>
  );
}

export default App;

2. Page.jsx:

  • Consumes the theme information using the useContext hook from the ThemeContext.
  • Renders a page with a header and an article, applying the theme dynamically to the container.
import { useContext } from 'react';
import Header from './Header';
import { ThemeContext } from './ThemeContextProvider';

export default function Page() {
  const { theme } = useContext(ThemeContext);
  return (
    <div id="app" className={theme}>
      <Header />

      <article>
        <h2>React Course</h2>
        <p>A course that teaches you React from the ground up and in great depth!</p>
      </article>
    </div>
  );
}

3. ThemeContextProvider.jsx:

  • Creates a ThemeContext using createContext.
  • Provides the ThemeContext.Provider component, wrapping its children and passing down the theme and a function (toggleTheme) to update the theme.
  • Manages the state of the theme using the useState hook.
  • Implements a function handleToggleClick to toggle between 'light' and 'dark' themes.
import { createContext, useState } from 'react';

export const ThemeContext = createContext({
  theme: '',
  toggleTheme: () => {},
});

export default function ThemeContextProvider({ children }) {
  const [theme, setTheme] = useState({
    theme: 'light',
  });

  function handleToggleClick() {
    setTheme((prevTheme) => {
      const oldTheme = prevTheme.theme;
      const newTheme = oldTheme === 'light' ? 'dark' : 'light';
      return {
        theme: newTheme,
      };
    });
  }

  const ctxValue = {
    theme: theme.theme,
    toggleTheme: handleToggleClick,
  };

  return <ThemeContext.Provider value={ctxValue}>{children}</ThemeContext.Provider>;
}

4. Header.jsx:

  • Consumes the toggleTheme function from the ThemeContext using the useContext hook.
  • Renders a header with a title and a button to toggle the theme.
import { useContext } from 'react';
import { ThemeContext } from './ThemeContextProvider';

export default function Header() {
  const { toggleTheme } = useContext(ThemeContext);
  return (
    <header>
      <h1>Demo Website</h1>
      <button onClick={() => toggleTheme()}>Toggle Theme</button>
    </header>
  );
}

In summary, this example showcases the use of React Context API to manage and share the theme state across different components in a React application. The ThemeContextProvider component is responsible for providing the theme information, and the useContext hook is used in child components (Page and Header) to consume and utilize this theme information. The toggleTheme function allows toggling between light and dark themes.

⚠️ **GitHub.com Fallback** ⚠️