Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice when not needed to render the component

I'm a bit new in React, so my question is regarding a best practice on something i'm trying to do. I might not being "thinking react" so I need your help.

I'm involved with a really big project related to sports. To minimise the number of components I need to create, I'm trying to use one single component to deal with multiple sports.

I will try to draw a basic scenario where it will match with a similar thing i'm trying to do.

-----------------------------------
|  module: Scoreboard             |
|                                 |
|  -----------------------------  |
|  | module: scores            |  |
|  |   Sydney 1 x 0 Melbourne  |  |
|  -----------------------------  |
|                                 |
|  -----------------------------  |
|  | module: results           |  |
|  -----------------------------  |
|                                 |
|  -----------------------------  |
|  | module: Footer            |  |
|  -----------------------------  |
|                                 |
-----------------------------------

With this scenario in mind, mind that all the props gets loaded when the component is loaded or through a parent.

I have 2 things that i need to do here on my script.

1 - Only display the component footer if there is a footer which is represented by this.props.footer 2 - Only display the component results if there is results which is represented by this.props.results

Right now i have a few user cases that I can do here.

User Cases (PARENT CONTROL)

On my render method I can do something like (don't mind the {...this.props} i only put there to represent i'm passing variables)

Case 1:

render: function() {
    var results, footer;

    if (this.props.results) {
        results = (<results {...this.props} />)
    }

    if (this.props.footer) {
        results = (<footer {...this.props} />)
    }

    return (
       <div class="scoreboard">
           <scores {...this.props} />
           {results}
           {footer}
       </div>
    );
}

The downside I see here is the amount of ifs inside the render. Not very readable, specially if we have a bit more than 2 components that does the same thing

Case 2:

render: function() {
    return (
       <div class="scoreboard">
           <scores {...this.props} />
           {this.props.results ? <results {...this.props} /> : ''}
           {this.props.footer ? <footer {...this.props} /> : ''}
       </div>
    );
}

Although I like this case better, Sometimes I have components that takes a big number of properties which can get to the same problem above (readability). Bare in mind i'm using {...this.props} to simplify the example

User Cases (CHILD CONTROL)

Which is the case I like better. Putting all the logic inside it's own component.

The problem is that I don't know how to stop the first render. And I also don't want to put a "display: block" on the page avoiding to add unnecessary markup where is not needed, so my idea here is really do not render the component at all if it's not needed. If i'm doing it wrong, or this is an anti-pattern, i would like some insight of it, like i said, i'm new with all of this react stuff, any comment is welcome.

So basically, like I said, I can't stop it from rendering.

Lets take the results component for instance, and lets there is a table and there is about about 10 lines of markup in it. Let's draw a case:

On my render method I can do something like

module: SCOREBOARD 

render: function() {
    return (
       <div class="scoreboard">
           <scores {...this.props} />
           <results {...this.props} isVisible={this.props.results} />
           <footer {...this.props} isVisible={this.props.footer}  />
       </div>
    );
}

module: RESULTS

render: function() {
    return this.props.isVisible ? (
       <div class="results">
             <table>
                ....
             </table>
       </div>
    ) : null;
}

I would control the return of the render with a property isVisible. Defaulting it to always false. Haven't found a good article about it, but i'm assuming this is not an elegant way.

I know we have a shouldComponentUpdate, but this won't stop the first render on the page, which will display some of the tables in our examples.

I wonder if anyone has some insight, a valid argument, or a solution to do what I'm trying to do. Remember that It's a big project, so I'm trying to avoid to create hundreds of components and instead having to use one component where there are a few variables that I could or not display the component on the page.

like image 277
Rafael Avatar asked Oct 27 '25 05:10

Rafael


1 Answers

If you have this:

render: function() {
    return (
       <div class="scoreboard">
           <scores {...this.props} />
           {this.props.results ? <results {...this.props} /> : ''}
           {this.props.footer ? <footer {...this.props} /> : ''}
       </div>
    );
}

You can rewrite it as different methods:

render: function() {
    return (
       <div class="scoreboard">
           <scores {...this.props} />
           {this.props.results ? this.renderResults() : ''}
           {this.props.footer ? this.renderFooter() : ''}
       </div>
    );
},
renderResults(){
    return (
        <results {...this.props} />
    );
},
renderFooter(){
    return (
        <footer {...this.props} />
    );
},

This way the conditional part never gets larger with more props, but you can still have that sub-render with the full thing.


To minimise the number of components I need to create, I'm trying to use one single component to deal with multiple sports

Having a lot of components isn't bad. You can have a lot of tiny components. When deciding the boundaries think about these (in terms of requirements changing tomorrow).

For siblings (multiple components with similar api, not nested):

  • will I need to update these components all at once? merge
    • example: a primary button is something you want to change once and have it affect everything
  • will I need to have differences between these components? split
    • example: the score board may have significant display differences

For parent/child:

  • does splitting make testing easier? split
    • example. list of inputs, testing events for one input is simpler than testing a list of inputs
  • does it reduce the complexity by splitting? split
  • does splitting result it pointlessly tiny components? merge

avoiding to add unnecessary markup

Having unnecessary markup is something that happens often in react. It's a tradeoff, but doesn't usually cause problems.

I would control the return of the render with a property isVisible

This is an anti-pattern. Unless you did this in every component, you're making assumptions about the user of the component which makes your code less modular and more difficult to maintain. Do conditional rendering in the parent unless you have a good reason to do otherwise.

like image 164
Brigand Avatar answered Oct 29 '25 21:10

Brigand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!