React : Communication between components using context

React : Communication between components using context

React : Communication between components using context api

Context API was introduced in React to simplify the way components communicate with each other. There are two types of communication that happen in React: a parent sending a message to a child and a child sending a message to a parent. The former is done using prop drilling, whereas the latter is done using events. As the component tree becomes complex, this communication becomes extremely hard to program and read. Redux-like third-party libraries were created to simplify this. But React's native Context API also provides a simplified way to achieve complex communication.

Table of contents

  1. Understanding the concept of Context
  2. Advantages of Context API
  3. Disadvantages of Context API
  4. Redux vs Context : Comprehensive comparison
  5. Context API Conclusion

Understanding the concept of Context

Provider Pattern

At a very high level why do components want to communicate in first place ? It is because one component is changing some data and other component has to react to it. It is fair to say that this means those two components "share" some state and make changes to it.

In software engineering this is a very common problem. Many other frameworks such as Android, Flutter etc. solved this using a concept called "Context".

You can think of Context as a simple object that is primarily created by an outer component. Once created, it is easily accessed by all the children of that outer component no matter how deeply they are nested.

Note that context is not a global state that is available for entire application. Though you can always make the outermost component create some context too. The advantage of context is that you can limit its creation to a specific subset of your component tree.

An example will make it clear.



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

const ThemeContext = createContext('light'); // Default value

function App() {
const [theme, setTheme] = useState('light');

return (
<ThemeContext.Provider value={theme}>
<Toolbar />
<Content />
</ThemeContext.Provider>
);
}

function Toolbar() {
const theme = useContext(ThemeContext);
// ... use theme to style the toolbar
}

function Content() {
const theme = useContext(ThemeContext);
// ... use theme to style the content
}


In above example App component is responsible for creating a ThemeContext object. Once created it wraps all its children in a ThemeContext.Provider component. Any component inside it can very easily access ThemeContext using the useContext api.

As you can see there is no prop drilling happening here. Toolbar component has no attribute like ThemeContext. Instead the Toolbar component obtains it from useContext hook.

Advantages of Context API

There are number of advantages of this approach.

  • There is no prop drilling and hence we need not define props for the components that want to use this context.
  • Intermediate components need not be aware of the context object at all if they do not need it.
  • Unlike Redux, the Context API is extremely simple to understand.

Disadvantages of Context API

  • Any kind of shared state is always bug prone.
  • Overusing this pattern makes it harder to read the code.
  • When a context object changes it forces all the consuming components to re-render. This means you should minimize changes to context object.

Redux vs Context : Comprehensive comparison

Between Redux and Context, Redux is lot more powerful and performance optimized but also adds complexity to your app. Context on other hand simple to use and is built in feature of React. One need not think of both as some kind of complimentary technologies rather you can use both in your application wherever it makes sense.

While Context can be seen as a shared state between components, Redux too is a shared state between components. Except that Redux allows components to subscribe to only specific subset of the state instead of relying on entire state object. What this means is there will be fewer re-renders of the components. This is a major performance optimization.

The second major difference between both is that Redux is a centralized store. A given Redux store represents the entire state of your application. Where as Context is more decentralized store because you can have multiple contexts , each with a diferent purpose. Redux being centralized can create a log of every operation that happens on it and we can trace how the application behaved over time. We can't do this easily with Contexts.

Redux is also unidirectional. Unidirectional (actions -> reducers -> store) where as context is bi-directional. You can read more about Redux here.

Context API Conclusion

Context API is a built-in API to simplify inter-component communication. It can be seen as an API that provides a shared state for all the components. It allows developers to reduce the complexity of their code by getting rid of prop drilling from their code. It makes the code cleaner to read. Overusing Context API might make the code harder to follow and introduce bugs, hence it should be used sparingly.