Understanding React useContext
Tags: javascript, react, codenewbie
Published: 2023-11-26 00:11:02

`useContext` is one of the React Hooks. As discussed in the previous blog post on React's Pros and Cons, the one-way data flow in React ensures a clean data flow architecture. Data from a parent referred to as props, can only be passed down to its child components and not vice versa. 

However, this approach can become cumbersome when dealing with the need to pass props down through multiple layers of components, creating a "prop-drilling" scenario. This involves passing data from parent to child, then from that child to another child, and so on—a sort of bucket relay.
This is where useContext proves to be incredibly useful.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gcf5li4kaxbbil6drrir.jpeg)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ypwrw8mmndx6zofcyu1.jpeg)

[Images are from react.dev](https://react.dev/learn/passing-data-deeply-with-context)

**Create the context in a separate file:**
Explanation: 
Contexts are defined in separate files to adhere to the principles of React and a component-based approach. This allows for a cleaner and more organized structure in your application.

Purpose: 
The creation of contexts, and the subsequent use of useContext, is not merely to avoid manually passing props. Instead, it serves the purpose of establishing a context-based communication channel within the component tree. This is particularly valuable for managing global states or sharing common functionality seamlessly across components.

```
import { createContext } from 'react';

const SomeContext = createContext(defaultValue)
```

**Provide it by wrapping the components:**
Explanation: 
To make the context value accessible to a part of the component tree, you use the `Provider` component. The Provider is responsible for passing down the context value through its value prop.

Purpose: 
The Provider wraps the component or components where you want the context to be available, ensuring that they have access to the shared context value.

```
** If you call the context from another page
import { MyContext } from './MyContext.js';

<MyContext.Provider value={ your data }>
  { Your components }
</MyContext.Provider>
```

**Use it in child components:**
Explanation: 
Similar to `useState()`, the `useContext()` hook is employed to access the context value within functional components. When you call `useContext(MyContext)`, it returns the current context value for the specified context object. This hook is particularly useful when working with contexts created using `React.createContext()`. The context can store not only data but also functions, providing a flexible mechanism for sharing functionality across components.

Purpose: 
By using `useContext()`, child components can seamlessly access the context value without the need for prop drilling. This enhances code readability and simplifies the passing of values between components.

```
import { useContext } from 'react';

const MyComponent = () => {
  const myData = useContext(MyContext);
};
```

The [reference](https://react.dev/reference/react/useContext) says, 

> The returned value is always up-to-date. React automatically re-renders components that read some context if it changes.

Whenever the value of a context changes, React automatically re-renders all the children components that are using that particular context. This re-rendering process ensures that the components stay in sync with the updated context value.

While this approach maintains overall data accuracy, it can become a drawback as the app grows larger. 

In such cases, `useReducer` seems a potential solution to address this challenge. In the next article, I'll delve deeper into this topic, and focus on utilizing both `useReducer` and `useContext`.