Using Render Prop as Inversion of Control

Sherry Hsu
3 min readDec 10, 2023

--

Inversion of Control

Inversion of Control is a pattern where an application hands over some responsibility to the external parties. In React, the responsibility is delegated via props

At work, there was an improvement I need to make to the TimelineSelector component , where I would like to update the Trigger Button to be a new Button component from the new Design System. The other UI components inside the TimelineSelector will remain using the old Design System for the time being.

As seen from the diagram above, in the monorepo package A, TimelineSelector renders TimelineSelectorDropdown from package B. However, I had to create the new Button from package A and pass it into TimelineSelectorDropdown to avoid bleeding the new Design System library into package B before a full rollout plan.

In this case, we can’t simply just pass the Button component as a prop into the TimelineSelectorDropdown because the the Button text was generated using complicated logics inside the TimelineSelectorDropdown Class Component. It was difficult to share such logics using Hooks.

// this will not work as we need to pass Button text and onClick function 
// from TimelineSelectorDropdown into the NewButton
<TimelineSelectorDropdown
button={<NewButton/> }
/>

Here, we can apply the Inversion of Control using the Render Prop pattern to delegate the responsibility of rendering the Button UI to TimelineSelector and still make sure correct Button text is rendered by passing the text into the delegated Button UI.

In the render prop pattern, the TimelineSelectorDropdown delegates the responosibility of rendering the Button UI out by accepting a prop which takes in a function that returns the Button element. The prop can be any name such as render, children…etc.

we pass a rendering function as a prop into the TimelineSelectorDropdown. The rendering function will return the NewButton while also accepting additional information like toggle, text to supplement the Button UI rendering.

Often, we choose children as the render prop! So we usually see render prop pattern implemented in the following manner.

Note

— I thought there will be no chance of using the Render Prop patterns after Hooks have become the popular way of sharing the logics between the components, but it is still very much needed when working with legacy code!
— Also, Render Props may have the added benefit of improving the performance of the app as it allows state to be shared with other siblings without lifting the state up and cause more components to re-render when state changes!

References

https://www.patterns.dev/react/render-props-pattern

Inversion of Control in React Youtube Video by Kent Dodds

--

--

Sherry Hsu

A software engineer passionate about learning and growth