Kent S. Dodds, the author of the material we are publishing today, says that recently a group of programmers with whom he was supposed to conduct a training on React became interested in the “render props” template, also called the “function as a descendant” template (in different his publications are referred to as "children as a function" or "function as child").
The React
documentation defines render render as a simple technique for transferring code between React components using a property whose value is a function. The component using render prop accepts a function that returns a React element. This component calls this function instead of implementing its own rendering logic. Kent recommends that those who are not familiar with the render prop template, read this
material and watch this
video , and then read on.

Kent says that when preparing for classes, he
experimented and decided to
ask his readers on Twitter what questions they have about render props, about the details of any other templates related to this, they would like to know, and what examples would help them with render props. In response to his tweet Kent received a lot of feedback. As a result, he decided to dwell on the three most typical questions regarding the render prop template and answer them, illustrating the answers with examples.
Question # 1: How does using the render prop template affect performance?
Perhaps this is the question that most often arises when I talk about the render prop template. In addition, in the comments on the above tweet, it was asked several times about performance. My answer to this question is very simple. Here I refer to the Ryan Florence
material on the use of features and performance in React. To quote the main conclusions of this material, we can say the following:
')
- Write the code as you are used to, realizing your ideas in it.
- Perform performance measurements to find bottlenecks. Here you can learn how to do it.
- Use
PureComponent
and shouldComponentUpdate
only when necessary, skipping functions that are component properties (only if they are not used in life-cycle interceptor events to achieve side effects).
If you treat opponents of premature optimization, then you do not need evidence that the built-in functions degrade performance. In order to think about their optimization, you need evidence to the contrary.
I would like to complement these findings. If you are really worried about embedding render prop functions and the possible negative impact of this on performance, just do not use the built-in functions.
class MyComp extends React.Component { renderDownshift = downshift => ( <div>{}</div> ) render() { return ( <Downshift> {this.renderDownshift} </Downshift> ) } }
Question number 2: How, when using render props, to avoid the appearance of overly complicated rendering code that is hard to read?
One of my readers, Mark Erickson, wondered how, using the render props template, not to put all the rendering logic into nested functions inside the
render()
method. He wanted to know if, for the sake of increasing the readability of the code, it was possible to break this logic into small functions, but
not to abandon render props.
Mark asks the right questions. Almost all the examples of using the render prop template that I have seen are reduced to placing all the rendering logic in one function. Usually in such cases, you can see the return command and one giant expression. These huge rendering features annoyed me, but I began to treat them much better when I realized that the only reason I didn’t like them was because I thought they were complex, although in reality it’s not .
In any case, since what we call “render props” are just functions that are called with arguments, you can do whatever your heart desires with them. As a result, I prepared a
couple of examples for Mark.
Mark ExamplesHere is a short version of the code for these examples.
function JustARegularFunctionComponent(props) { // return <div>{/* */}</div> } function App() { return ( <div> <div> With a totally different component. Thanks React composibility! </div> <RenderPropComp render={arg => ( <JustARegularFunctionComponent {...arg} /> )} /> <hr /> <div> Inline! You don't have to make it an implicit return arrow function </div> <RenderPropComp render={arg => { // <-- notice the curly brace! // return <div>{/* */}</div> }} /> </div> ) }
Question number 3: How to organize access to the arguments of the render prop-functions in the methods of processing events of the life cycle of the component?
Another fairly common question is how to access the render prop function arguments in the component's lifecycle processing methods. The difficulty here lies in the fact that these functions are called in the context of the
render
component, so
it is not clear how to work with the data passed to them, say, in
componentDidMount
.
In fact, the answer to this question is hidden in the answer to the question of Mark, which we discussed above. Please note that due to the React's composition capabilities, we can create a separate component and simply redirect the arguments to the properties of our component. For example, it can be done
like this .
class RegularClassComponent extends React.Component { componentDidUpdate() {
My friend
Donavon will be sad if I don’t tell about his favorite pattern “
component injection ”. Using this template, you can achieve our goal even easier, and the code will look cleaner:
class RegularClassComponent extends React.Component { componentDidUpdate() {
You can work independently on implementation details. In addition, you can take a look at the new
library that Donavon created after our talk about render props.
Results
I think the render prop template is just great technology, and I look forward
to adding to the awesome-react-render-props list that
Jared Palmer is working on. In this template, I especially like the fact that it can include the component logic and not harm the ability to customize the system and not complicate the markup. I think, as far as render props is concerned, there is still a lot of interesting things waiting for us.
Dear readers! Do you use the render props template in your React projects?