When we start learning through building with React we are introduced to the power and ease in which we are able to pass data around our projects through Props. This is great! . We can pass a name prop to our component and in a few taps of the keyboard we have a component which renders "Hello {Name}". When it comes time to start building something slightly larger and more complex than a single file, we find that threading props around a project can get pretty annoying / confusing if a growing number of components need access to this data.
This is where using context can help us.
Often we will find that multiple components in a stack need access to a shared state which is held in the highest parent component. A way we can do this is through passing the state through props to each component.
Here we have the parent component named Parent which holds the state that the component ChildC needs access to. By passing the state of the parent through props, childC is able to access and use the data. This is called prop drilling where we are drilling the data deeper and deeper into the component stack. Prop drilling can be useful if the stacks are fairly small but when the stack grows in size it can become quite annoying to set a large number of props. We can also find ourselves in a situation where components that don’t need access to the data still have to pass this data deeper.
A tool in our React kit we can use is Context . Context is used when we determine that some data should be accessible globally. For example it may be useful to share user information with many components.
Lets see how we can do this :
Here we have created a Context object . When react renders a component that subscribes to this object it reads the current context value from the closest matching provider.
We use a provider component to wrap the Parent which passes the user data down the component tree which means that any component in the tree can now access this data. The provider component takes a value prop which is passed to all consumers. importantly all consumers of a provider will re-render when the value of the provider changes.
As we have wrapped children in the parent component all of the child components have access to this context if needed . In this example we have decided that ChildC would need access to this context so we provide access to the context through the useContext hook const consumedUser = useContext(UserContext)
Using context has the benefit of allowing us to consume data in a component wherever it is in our App , however sometimes using context is not the best option for our code . Often reorganisation of the components may be a better option .
If you have made it this far I would like to thank you for reading and I hope you have learnt something new that you are able to use in your own projects.
Photo : Thespruce.com