21

Let's say I have a simple component that may or may not render a Counter.

What's the best practice in React to express a blocked code path? Should it return null, [], or a Fragment?

class App extends Component {
  renderCounter() {
    if (!this.props.shouldRenderCounter) {
      // // which should I return?
      // return; 
      // return null; 
      // return []; 
      // return <React.Fragment />; 
    }
    return <Counter />;
  }

  render() {
    return (
      <div>
        {this.renderCounter()}
      </div>
    );
  }
}

I think null is the clearest, but I can imagine it causing problems if the context around the return function expects a component. [] and Fragment both seem like fine options to me, except Fragment is a little easier to read. What's the difference?

Tai
  • 490
  • 4
  • 18

2 Answers2

20

Returning null is recommended by the React team:

In rare cases you might want a component to hide itself even though it was rendered by another component. To do this return null instead of its render output.

Owen Pearson
  • 449
  • 3
  • 9
  • Could anyone provide with the reasoning behind it? I find it a bit anti intuitive that you have a parent rendering a child, and the child then deciding not to render itself. – RTYX Feb 09 '21 at 07:32
  • @RTYX It can be useful in situations where you need the logic of whether a component renders to live inside the component itself. As the quote in my answer says; this is a "rare case", and in general it is better to prevent the component from rendering at all than to return `null`. – Owen Pearson Feb 10 '21 at 10:36
  • Sure, I understand that reason, I just have a hard time imagining a situation in which that logic cannot exist in the parent element but it can exist in the child, and if it can exist in either of them, I wonder why would I put it in the child. – RTYX Feb 10 '21 at 13:19
  • I think a common example might be a component which fetches remote data inside a call to `useEffect` as soon as it renders for the first time, but while the fetch is pending it returns `null` because it's not ready to display anything. – Owen Pearson Feb 10 '21 at 15:32
1

You dont need to create an extra function for it.

This will do the job:

class App extends Component {
  render() {
    return (
      <div>
        {this.props.shouldRenderCounter && <Counter />}
      </div>
    );
  }
}
Michael Ploeckinger
  • 1,616
  • 1
  • 11
  • 24
  • 2
    My case is a contrived example. The actual code can’t be one-lined as easily – Tai Nov 28 '18 at 17:55
  • 2
    Yes. This doesn't answer the question. Came here for same reason as OP. – eivindml Mar 14 '19 at 10:21
  • 1
    In defense of this answer: I think the implied point is that you shouldn't be calling a separate method on your Component to render *part* of that Component. That "subsection" of the Component would likely work better as an actual, separate Component with its own `render()` method. So in OP's example, it would actually be cleaner to extract the logic from `renderCounter()` into its own Component. Then, decide whether to include that Component as part of the caller's `render()` method (similar to the example in this answer). – cariehl Apr 24 '21 at 20:49