In React or VueJS, we often author components that are considered as layout components, which sets the generic layout UI like header/sidebar/footer etc so that they can be reused in different places. Each time a layout component is called, it does not care about what to be inserted into its children. In VueJS, we have Slots API and in React we have props.children to achieve that.
However, in certain scenarios we want to pass some data from parent into its children, even the parent does not know what kind of component will be of its children, given the fact that it is a generic layout component. How can we do so?
Let’s make a demo: The parent component will start counting how many seconds you have stayed in this web page (yep, that’s exactly what you saw in reactjs.org) and child component will consume this count and render it.
VueJS
We will resort what is referred as Scoped Slots
|
In the parent TimeOnPage we can use v-bind to bind an object to slot with structure like
|
so in child components can access this object. It is a common practice to name this object to slotProps in child v-slot directive but you can actually name it to whatever you would like.
React Hooks
With React Hooks we can easily share state between components by using customized hooks:
|
However this is not exactly same as our topic, since we want to keep the data in the parent component and share in its immediate children. Here we can use a technique that is often referred as Render Props:
|
In this example, TimeOnPage will accept a function as props (The prop name can be called anything but usually we will name it as render) and pass its data as function arguments. The function will return a component which can access these arguments in this closure.