Solving prop drilling in React with ContextAPI
Tags: react, javascript, webdev, beginners
Published: 2023-04-10 13:34:28

## Prop Drilling

The most simple way to pass data between components is using props, but it can lead to a messy code and probably making it unmaintainable, specially with prop drilling, where a props have to be passed to multiple layers of components:

![Five blue blocks stacked vertically and with arrows representing props being passed to the next block below](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k5qihyvqx0w56ysj09yg.png)

## Solving this (and maybe others) issue(s) with Context

| Context lets you write components that “adapt to their surroundings and display themselves differently depending on where (or, in other words, in which context) they are being rendered. - [react.dev](https://react.dev/learn/passing-data-deeply-with-context)

Basically, Context enables us to pass data through the component tree without having to pass props down manually at every level (prop drilling for example).

## How to use it?

- First, we need to create a Context using `React.createContext` and then we can use it in our components

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

  export const MyContext = createContext()

  // If you'se using TypeScript, you can also pass a default value to the context with the type of the value you're going to pass
  export const MyContext = createContext({} as MyContextType)
  ```

- then we need to wrap all the components we want to use the context in a `Provider` component

  ```jsx
  import { MyContext } from './MyContext';

  export function App() {
    return (
      <MyContext.Provider value={/* value of your context */}>
        <ComponentA />
        <ComponentB />
        <ComponentC />
      </MyContext.Provider>
    );
  }
  ```

- now you can access the data from your context in any component that is wrapped in the `Provider` component using `useContext`:

  ```jsx
  import { MyContext } from './MyContext';

  export function ComponentA() {
    const value = useContext(MyContext);
    return <div>{value}</div>;
  }
  ```

## Conclusion

- That's it! I honestly believe that the best way to learn anything is trying for yourself, so I encourage you to try to create a simple counter app using Context.
- Also, if you want to see it in action, check this [simple timer app on my Github](https://github.com/ist4/timer-react-ts)
  - In this app I used Context to share the state of the timer between the `Home`, `Countdown` and `NewCycleForm` components


## Reference

- [Passing data deeply with context | react.dev](https://react.dev/learn/passing-data-deeply-with-context)
- [React Context for begginers - freeCodeCamp](https://www.freecodecamp.org/news/react-context-for-beginners/)
- [Prop Drilling: o que é? - Alura](https://www.alura.com.br/artigos/prop-drilling-no-react-js)
- [`createContext` | react.dev](https://react.dev/reference/react/createContext)
- [`useContext` | react.dev](https://react.dev/reference/react/useContext)
- Cover image by <a href="https://unsplash.com/@afgprogrammer?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Mohammad Rahmani</a> on <a href="https://unsplash.com/pt-br/fotografias/W-LQbAUhE64?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>