reactjsreduxreact-reduxprop-drilling

Best way to pass props through multiple levels in React (Prop drilling)


Let's say we have the following hierarchy in a big React app.

Child1 is parent of Child2, Child2 is parent of Child3, etc and we can have n number of children. We also have a Redux store with props1, props2, props3...

Now let's say Child7, which is a relatively small component, needs access to props2 from Redux (which is an object, to make it more complex a little)

In your opinion, what is the best ( in terms of efficiency/readability ratio ) approach to manage Props Drilling?

  1. Have child1 as "Container". Connect it to redux store, take all the props and then pass it to the others as
<Child2 {...props} />

then inside Child2

<Child3 {...props} />

...etc until <Child7 {...props} />

The problem: It's pretty obvious with this approach.

  1. Having all the components, small or big, connect to the store if they actually need a prop from there and only Drill the Props from one component to another if it's about max 2 levels.

The problem: What if Child3, Child7, Child12 etc needs props from the store. I wouldn't think it's a good idea to connect a component the the store even if we have selectors to get exactly what it's needed

  1. (1) Connect just specific children to the store and make "local containers" based on Business Logic

  2. Get all the props in Child1, create some Context Providers at Child1 level and then only Consume them in the children that needs them. Basically let's say (in top level, Child1)

<Props1ContextProvider>
{....}
</Props1ContextProvider>

wrap it in a nice hook like useProps1Context() and use it like const { props1 } = useProps1Context() only in the components that needs those

The problem: Well what's the point of redux of we're using it halfway through and then switch to context?


Solution

  • The recommended approach is to connect more components to the store (similar to your #2): https://redux.js.org/style-guide/style-guide#connect-more-components-to-read-data-from-the-store.

    Selecting data from the store is very efficient (assuming you made sure your selectors always return the same reference if the data didn't change), I don't think there is any reason to drill down props that the child component can obtain directly from the store (even if it's just one level down). Approaches #1 and #3 will be worse for performance, as a lot more components will need to rerender for every state change.

    You still need to send specific props to the children (like ids) so that they know where to look for in the store, and you may still want to use Context if for instance you need to access the id of the containing Child2 from a Child7 (you cannot get that from Redux, and prop drilling would be painful).