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.
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
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.
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):
For parent/child:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With