261

I have a notification component, and I have a timeout setting for it. After timeout I call this.setState({isTimeout:true}).

What I want to do is if already timeout, I want just render nothing:

render() {
  let finalClasses = "" + (this.state.classes || "");
  if (isTimeout){
    return (); // here has some syntax error
  }
  return (<div>{this.props.children}</div>);
}

The problem is:

return (); // here has some syntax error

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
Xin
  • 33,823
  • 14
  • 84
  • 85

8 Answers8

427

Yes you can, but instead of blank, simply return null if you don't want to render anything from component, like this:

return (null);

Another important point is, inside JSX if you are rendering element conditionally, then in case of condition=false, you can return any of these values false, null, undefined, true. As per DOC:

booleans (true/false), null, and undefined are valid children, they will be Ignored means they simply don’t render.

All these JSX expressions will render to the same thing:

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

Example:

Only odd values will get rendered, because for even values we are returning null.

const App = ({ number }) => {
  if(number%2) {
    return (
      <div>
        Number: {number}
      </div>
    )
  }
  
  return (null);           //===> notice here, returning null for even values
}

const data = [1,2,3,4,5,6];

ReactDOM.render(
  <div>
    {data.map(el => <App key={el} number={el} />)}
  </div>,
  document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id='app' />
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
  • 12
    Why are you returning (null) and not simply null? – wederer Aug 02 '18 at 11:51
  • 12
    @wederer there is no difference between `return null` and `return (null)` they are same :) – Mayank Shukla Aug 02 '18 at 11:55
  • 1
    But the way, you can't just drop out of your function (which is the same as returning undefined). If you don't have any `return` then React gives an error. So the `return null` is required. – John Henckel May 13 '20 at 15:39
  • Btw, returning empty array from component or JSX expression still counts by react as valid empty value. This is in particular useful to understand while making `data.map(...)` in JSX when `data` is variable which could have no elements in it. – Mesqalito Jun 15 '22 at 21:11
  • 3
    @MayankShukla `return null` and `return (null)` are not the same; a dimension of the result may be the same but the latter includes 2 useless characters – Geoffrey Hale Jul 14 '22 at 17:20
  • @GeoffreyHale That clarifies :) – emre-ozgun Oct 14 '22 at 13:25
50

Some answers are slightly incorrect and point to the wrong part of the docs:

If you want a component to render nothing, just return null, as per doc:

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.

If you try to return undefined for example, you'll get the following error:

Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.

As pointed out by other answers, null, true, false and undefined are valid children which is useful for conditional rendering inside your jsx, but it you want your component to hide / render nothing, just return null.

EDIT React 18:

React 18 will allow rendering undefined instead of throwing. See this announcement.

jhujhul
  • 1,527
  • 12
  • 11
22

Yes you can return an empty value from a React render method.

You can return any of the following: false, null, undefined, or true

According to the docs:

false, null, undefined, and true are valid children. They simply don’t render.

You could write

return null; or
return false; or
return true; or
return <div>{undefined}</div>; 

However return null is the most preferred as it signifies that nothing is returned

Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
11

If you are using Typescript and your component/function has return type React.Element, you will get the following error.

Type 'null' is not assignable to type 'ReactElement<any, string | JSXElementConstructor>'.

The solution is React.Fragment.

return <React.Fragment />

or

return <></>
Fatih Bulut
  • 2,385
  • 1
  • 15
  • 12
  • 2
    According to this eslint rule, empty fragments are not advisable https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-useless-fragment.md – R. de Veen Feb 11 '22 at 13:37
  • 4
    Null is more performant too. With null there's nothing for react to process, it just moves on. A fragment has to be processed, even if it isn't very much. – Yedidya Rashi Sep 29 '22 at 18:43
7

Slightly off-topic but if you ever needed a class-based component that never renders anything and you are happy to use some yet-to-be-standardised ES syntax, you might want to go:

render = () => null

This is basically an arrow method that currently requires the transform-class-properties Babel plugin. React will not let you define a component without the render function and this is the most concise form satisfying this requirement that I can think of.

I'm currently using this trick in a variant of ScrollToTop borrowed from the react-router documentation. In my case, there's only a single instance of the component and it doesn't render anything, so a short form of "render null" fits nice in there.

Chris Kobrzak
  • 1,044
  • 14
  • 20
  • 1
    The code has been already finished, but I like this style, looks the simplest code. – Xin Jun 26 '18 at 04:08
4

for those developers who came to this question about checking where they can return null from component instead of checking in ternary mode to render or not render the component, the answer is YES, You Can!

i mean instead of this junk ternary condition inside your jsx in render part of your component:

// some component body
return(
  <section>
   {/* some ui */}
   
   { someCondition && <MyComponent /> }
   or
   { someCondition ? <MyComponent /> : null }

   {/* more ui */}
  </section>
)

you can check than condition inside your component like:

const MyComponent:React.FC = () => {
  
  // get someCondition from context at here before any thing


  if(someCondition) return null; // i mean this part , checking inside component! 
  
  return (
    <section>   
     // some ui...
    </section>
  )
}

Just Consider that in my case i provide the someCondition variable from a context in upper level component ( for example, just consider in your mind ) and i don't need to prop drill the someCondition inside MyComponent.

Just look how clean view your code gets after that, i mean you don't need to user ternary operator inside your JSX, and your parent component would like below:

// some component body
return(
  <section>
   {/* some ui */}
   
   <MyComponent />

   {/* more ui */}
  </section>
)

and MyComponent would handle the rest for you!

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
amdev
  • 6,703
  • 6
  • 42
  • 64
1

We can return like this,

return <React.Fragment />;
Siluveru Kiran Kumar
  • 699
  • 1
  • 10
  • 16
  • 2
    is this better or worse than returning `null`? – strider Aug 09 '19 at 21:10
  • 1
    @bitstrider using Fragment instead of null triggers just a lose of memory. – koo Aug 29 '19 at 18:17
  • 2
    not sure why this answer is downvoted, its shows the developer's intent explicitly – ktingle May 04 '20 at 01:55
  • 1
    @ktingle From react docs: "A common pattern in React is for a component to return multiple elements. Fragments let you group a list of children without adding extra nodes to the DOM." null is more correct, "React docs, 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." – row Feb 04 '22 at 14:34
0

Returning falsy value in the render() function will render nothing. So you can just do

 render() {
    let finalClasses = "" + (this.state.classes || "");
    return !isTimeout && <div>{this.props.children}</div>;
  }
schrodinger's code
  • 2,624
  • 1
  • 25
  • 19