How to avoid Prop-drilling in React

Jerome Franco
3 min readJul 7, 2019

--

So we all know that React is a great framework, it follows a component based architecture, it encourages lifting state up, break up your UI into small components and pass data from top to bottom using props.

This a good approach to build UI as it facilitates better code reuse and it makes your app more predictable and easier to test. However there’s a caveat to that.

When you’re passing data thru props from top to bottom of the component tree, you probably experienced this frustration where you want to pass data from the top level component to a 3rd or 4th level level component but you end up passing these data to components on each level of the tree.

This is what we call Prop-drilling!

Let’s try to look at an example code with prop-drilling.

Prop-drilling Example

We have a trivial example with 3 components (TodoPage, TodoList and TodoItem) to demonstrate prop-drilling.

TodoPage Component
TodoList Component
TodoItem Component

As you can see in the example, TodoItem needs onDelete and canDelete from the TodoPage but those values have to pass thru the TodoList even if this component doesn’t need them. And if you have a linter, you’ll probably have to define prop types on the TodoList for these props as well.

Okay enough of that! Let’s now take a look at some solutions to this madness.

Solution #1 — Context API

If you’re not familiar with the Context API, I encourage you to check it out first here. But in case you’re already familiar with it, let’s see how we can implement the example above using it.

I’m going to merge the components into one gist for the sake of saving space 😁

Merged TodoPage, TodoList and TodoItem

Okay so, in the code above we were able to avoid passing onDelete and canDelete to the TodoList. Using the Context API we can directly pass data from the TodoPage to the TodoItem or to any leaf component in the component tree.

Context API is a great way to avoid prop-drilling but it isn’t a simple solution. It requires you to do some extra work to take advantage of it. Another caveat is that it tightly couples your component with a context, which means it will be a bit difficult to facilitate reuse.

Solution #2 — Render Props

This solution is simple and one that I prefer. If you haven’t heard of Render Props, go ahead and check it out first here.

Okay so, assuming that you’re already familiar with it, let us implement the prop-drilling code example using render props.

Render Props Version

In the code above, instead of hard-coding TodoItem inside the TodoList, we provide a function prop called rendeItem so that we can declare TodoItem in the TodoPage. This way, we can directly pass data from the TodoPage to the TodoItem.

Also, since your components are not tightly coupled with a context they become more reusable.

Conclusion

This isn’t to say that prop-drilling is an anti-pattern, in fact if you just want to bypass one level in the tree and pass 2 props like in our trivial prop-drilling example, you’ll be better off passing props thru every level in the tree.

However, as soon as the tree gets deeper and you‘re already starting to feel that frustration, you might want to consider either of the two solutions I mentioned.

👉 If you like this article and if you find it helpful, please give it a clap. Also, don’t forget to follow me here on medium for more contents. 👈

--

--