If you've done much with React, you've probably run into this kind of scenario:
class Tabs extends React.Component {
constructor(props){
...
For further actions, you may consider blocking this person and/or reporting abuse
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
I also wanted to mention the optimization aspect of this article's refactor as well as Sergey did.
Once
TabButton
is wrapped inReact.memo
or turned into a Pure Component (as a Class Component), then it'd preventTabButton
from rendering unncessarily.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.
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.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.
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.
Great real world example! Just ran into a really similar issue earlier today and would not have thought to pull it out like that
Thanks, Jonathan
Good explanation
Not using classes (but functional components and hooks) will automatically save you from such solutions.
Would you share more how "function components + hooks" can save one from having
renderThings
?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 likeconst renderThing = () => {}
where I would immediately see that it is the component itself and I just have to rename it toThing
.This was great, thank you, Jonathan.
Good catch! I don’t believe so. Need to update that code.