1

I came across some code in review and had a question on best practices. Here's the scenario:

I've got a Hyperlink component with a url prop. If for some reason url is falsy, Hyperlink renders null.

simplified example:

const Hyperlink = ({ url }) => {
  return !url ? null : <SomethingElse url={url} />;
};

Does this logic belong in the Hyperlink component, or should it be the responsibility of the parent component to determine whether or not to render something?

example:

const MyParentComponent = ({ url }) => {
  return !url ? null : <Hyperlink url={url} />
};

This keeps Hyperlink dumb, with the downside of having to sprinkle that logic in places url is optional.

phasma
  • 624
  • 6
  • 18
  • That parent component example doesn't make a lot of sense, it's literally just acting as "still just the Hyperlink component, but now with an extra level of indirection". Generally, the parent should decide what _it_ needs to render as. If its props/state do not include a url to show as a link, then it should not render a link. – Mike 'Pomax' Kamermans Apr 03 '22 at 17:46
  • 1
    @Mike'Pomax'Kamermans It looks like this parent component is just an example to keep it simple. The question looks more generic, though - if the parent should be responsible for the logic of displaying/not displaying its children, or this functionality should be encapsulated in the child components themselves. – Nikolay Apr 03 '22 at 17:52
  • Correct, this example is contrived. – phasma Apr 03 '22 at 19:28

3 Answers3

2

If the conditional rendering is :

condition ? something : null

I prefere using:

condition && something

Since conditional rendering should be used for cases like:

condition ? something : somethingElse

Back to your question, if the Component has some heavy calculations before the return, it's common sense that you are wasting resources performing them since it won't return nothing if condition is false, so it' s better to use:

condition && <Component/> 

But in most cases, especially if you have stateless components with no logic like that one, you won't experience particular differences between the two approaches, basically by doing the conditional rendering inside the component, you are just wasting a React.createElement().

I personally use

condition && <Component/>

in cases like that, if it's possible, since I find to be very semantically uncorrect for a Component to possibly render nothing. If you call your Component HyperLink, I expect it to return something, possibly a link. There are cases where you are forced to return nothing, and it's okay, but I try to avoid it.

Cesare Polonara
  • 3,473
  • 1
  • 9
  • 19
  • Thanks @Cesare Polonara! This is helpful! re: ternary vs `&&`: I've been bitten by the LHS being falsy but not a boolean, leading to rendering out the LHS instead of nothing. https://kentcdodds.com/blog/use-ternaries-rather-than-and-and-in-jsx If you can guarantee the left hand side is a boolean, I like your preference more as well. – phasma Apr 03 '22 at 19:27
  • 1
    Yeah there are just two falsey cases that bite 0 and NaN, but as Kent says in the conclusions it's enough to make a Boolean coercion of falsey values to be safe in any case since React handles false the same as null. Readability is all a matter of a subjective experience after all! – Cesare Polonara Apr 03 '22 at 20:12
2

I would say, as a generic rule, there is "avoid surprises", or "reduce WTFs per minute", or "explicit is better than implicit". Getting null instead of a <Link /> is well sort of a "surprise".

I think it may be somewhat similar to "pointers vs references", when a pointer can have a null value, whereas a reference can't. References are safer, because you don't need to worry about the null value. Consider passing that <Link /> component to some callback or argument. For example, SomeComponent here may be shocked by getting null:

const content = <Link>;
<SomeComponent contents={content}>

But in principle I think both approaches are fine.

Nikolay
  • 10,752
  • 2
  • 23
  • 51
-1

Usually these type of checking should be done using Typescript. Answering to your question it should depend upon your project scenario.

If you feel the url the Hyperlink component will receive can be null or undefined you can put the check in the Hyperlink component.

But if you think only in MyParentComponent the case will occur where url will be null you can think of conditionally rendering the component.

ravi singh
  • 19
  • 5