1

Are there any downsides to this sort of thing:

render() {
    return (
        <div className={"the-page"}>
            <div className="left-col">
                 {this.renderLeftColumnBoringStuff()}
            </div>
            <div className="main-panel">
                <ExitingPanel stuff={this.state.stuff_that_changes}/>
            </div>
        </div> )};

renderLeftBoringStuff = () => (
    <div className="left-column">
        button className="btn s primary" onClick={this.setExploreMode}>
             {_("Explore")}
        </button>
            (etc ... more of these)
    </div>
);

The motivation is that the structure of the page is clear in this layout, and the boring stuff doesn't need a functional component, it has no props, doesn't need to be re-rendered - it's just buttons and static layout that can be described separately.

I'm doing it, and I'm asking myself "why aren't you making this a pure component?", and I'm answering "because even that seems heavy weight to just refactor some boring definitional stuff".

The twist is that the boring stuff has references to functions on the current component, which are called when the buttons in there are pressed, so it is non-trivial to pass those into a subcomponent.

From comments below, I think the question can also be viewed this way:

How is it different to either in-line, factor out in a function or factor out in a component? I think I understand that if there are props and state involved, then a separate component can render independently, which can be a good thing. That leaves me with the question of "what if there aren't?"

(This question is about whether there are technical downsides that I may not appreciate when forming an opinion about this, not searching for opinions themselves.)

GreenAsJade
  • 14,459
  • 11
  • 63
  • 98
  • It depends. setExploreMode and onSomething aren't shown. – Estus Flask Jan 16 '19 at 08:09
  • @estus Can you elaborate on what details of those would make a difference? (I got rid of onSomething from my question, it was duplicating the illustrative purpose of setExploreMode). – GreenAsJade Jan 16 '19 at 08:13
  • If you're able to extract a part to a separate component, it's a good thing to do. It's a matter of taste after all. From the code, it's unclear why `
    ` should be extracted and `
    ` should not.
    – Estus Flask Jan 16 '19 at 08:16
  • @estus My question will get deleted if it boils down to taste :) I really am trying to ask "what are the technical implications of doing this?". How is it different to either in-line, factor out in a function or factor out in a component? I think I understand that if there are props and state involved, then a separate component can render independently, which can be a good thing. That leaves me with the question of "what if there aren't?" – GreenAsJade Jan 16 '19 at 08:18
  • 3
    I see no technical implications besides testing. You have more options to test it when it's separate component, though you will likely want to test the whole view as single component here. It really depends on the case. In this case I don't see any difference, but I also don't see a reason to extract renderLeftBoringStuff part, it's not that bulky. If renderLeftBoringStuff can be reused, it's certainly worth to be extracted to a component. – Estus Flask Jan 16 '19 at 08:23
  • Thanks for digging in and finding out what I'm asking. I think that if the answer could be phrased as "there is no technical difference between in-lining and factoring into a function" it turns out that this would be the answer to my question. If that is true, I'd be happy to accept that answer. – GreenAsJade Jan 16 '19 at 08:29

1 Answers1

1

There is no practical difference besides testing, the size of a class and some difference in performance. If a part that was extracted to a method is bulky, a class doesn't decrease in size and can be hard to be read and maintain. It may be worthwhile to test a part in separation. There is insignificant performance difference (a component provides abstraction layer that has some overhead) but it can be ignored in general, unless proven otherwise; when a part is extracted to functional component, it can be called directly for optimization purposes, too.

Another consideration is that with the introduction of React hooks, functional components are becoming universal choice. Refactoring a huge class to functional component for the sake of uniformity will result in a huge function that may be harder to maintain.

Components are more suitable for isolated unit tests, particularly with Enzyme shallow renderer. If a part is supposed to be reused, it's a good practice to extract it to a component regardless of its size and complexity.

In this example renderLeftBoringStuff is small and simple piece of a view that doesn't benefit from being tested separately. On the other hand, it doesn't really benefit from being extracted from render due to its size.

As a rule of thumb, if a part is big and complex enough so it certainly deserves to be extracted to a method, it may benefit from being a component even more.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565