DEV Community

React Anti-pattern: renderThing

Jonathan Cutrell on May 24, 2019

If you've done much with React, you've probably run into this kind of scenario: class Tabs extends React.Component { constructor(props){ ...
Collapse
 
js2me profile image
Sergey S. Volkov

Agreed with you Jonathan!
Also I want to tell a couple words about coming advantage of separating component on sub components instead of using the one big react component
It gives advantage because rendering of the react component works by comparing previous props and next props inside react engine. And in this way React can easy check what needs to update or not

Collapse
 
dance2die profile image
Sung M. Kim

I also wanted to mention the optimization aspect of this article's refactor as well as Sergey did.

Once TabButton is wrapped in React.memo or turned into a Pure Component (as a Class Component), then it'd prevent TabButton from rendering unncessarily.

Collapse
 
lopis profile image
João L.

I don't totally agree.

The author here did more than just remove the "renderThing" method. He created a new component called TabButton. That is great - improves readability, testability, and probably performance. But is it really any difference to have a function call vs an inline piece of javscript inside the curly brakets? It's still just a function. React doesn't care where you put your map function in order to check for updates.

Collapse
 
js2me profile image
Sergey S. Volkov

I think yes, we have differences in performance between {someFunc(data)} and <someComp></someComp>
Yeah, you're right about that someComp it is the same function React.createElement but I talked about that inside this function React have ability to compare outer props with current props and after fully compared it will call re-render.
But if we will talk about {someFunc(data)} that will be a bit different between using component because it will try to call check for updates all child components.

Collapse
 
mgtitimoli profile image
Mauro Gabriel Titimoli • Edited

There are times where creating a new component doesn't make sense and breaking the jsx into small render functions is not a bad idea as it follows what we do in other contexts, like for example when there is a big function and we break it into smaller ones to improve legibility.

Having said this, there are times this is overused, and for these cases I agree it would be better to extract that into another component.

To summarize, it's never a good idea to go with an "all or nothing" approach, imo it's better to be on a "it's depends" motto and evaluate the case.

Having render helpers is not a bad idea or antipattern but we should not overuse this and create another component(s) given the case.

Collapse
 
hlherrera profile image
Hermes L Herrera • Edited

I suggest to develop a component in another fashion.
Instead of array of props, is more functional and reusable, to use an array of children. Component composition.

Ex.


....
....

Render props, is a great powerfull pattern to use in this case.

Collapse
 
theblairwitch profile image
Blair McKee

Great real world example! Just ran into a really similar issue earlier today and would not have thought to pull it out like that

Collapse
 
kioviensis profile image
Max Tarsis

Thanks, Jonathan
Good explanation

Collapse
 
wintercounter profile image
Victor Vincent • Edited

Not using classes (but functional components and hooks) will automatically save you from such solutions.

Collapse
 
dance2die profile image
Sung M. Kim • Edited

Would you share more how "function components + hooks" can save one from having renderThings?

Collapse
 
wintercounter profile image
Victor Vincent

What you did there is basically extracting the return value of your renderThings function. The only way with FC to couple that value inside the component is to store it in a local variable which feels illegal enough for me to not to do it. This would also enforce a pattern like const renderThing = () => {} where I would immediately see that it is the component itself and I just have to rename it to Thing.

Collapse
 
jwankhalaf profile image
Jwan Khalaf

This was great, thank you, Jonathan.

Collapse
 
jcutrell profile image
Jonathan Cutrell

Good catch! I don’t believe so. Need to update that code.