333

Basically, I have a react component, its render() function body is as below: (It is my ideal one, which means it currently does not work)

render(){
    return (
        <div>
            <Element1/>
            <Element2/>

            // note: logic only, code does not work here
            if (this.props.hasImage) <ElementWithImage/>
            else <ElementWithoutImage/>

        </div>
    )
}
3
  • 2
    Yeah this is a very common issue to run into and a great question! Maybe wording it a little different and showing what happens you run this particular code (also consider formatting it a bit) would help clear up exactly the issue. Commented Nov 8, 2016 at 1:07
  • Yes, it is a wrong one (ideal one). I have just updated the question to clear the issue. Thanks Commented Nov 8, 2016 at 4:19
  • official documentation: react.dev/learn/conditional-rendering Commented Mar 8, 2024 at 10:12

25 Answers 25

521

Not exactly like that, but there are workarounds. There's a section in React's docs about conditional rendering that you should take a look. Here's an example of what you could do using inline if-else.

render() {
  const isLoggedIn = this.state.isLoggedIn;
  return (
    <div>
      {isLoggedIn ? (
        <LogoutButton onClick={this.handleLogoutClick} />
      ) : (
        <LoginButton onClick={this.handleLoginClick} />
      )}
    </div>
  );
}

You can also deal with it inside the render function, but before returning the jsx.

if (isLoggedIn) {
  button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
  button = <LoginButton onClick={this.handleLoginClick} />;
}

return (
  <div>
    <Greeting isLoggedIn={isLoggedIn} />
    {button}
  </div>
);

It's also worth mentioning what ZekeDroid brought up in the comments. If you're just checking for a condition and don't want to render a particular piece of code that doesn't comply, you can use the && operator.

  return (
    <div>
      <h1>Hello!</h1>
      {unreadMessages.length > 0 &&
        <h2>
          You have {unreadMessages.length} unread messages.
        </h2>
      }
    </div>
  );
Sign up to request clarification or add additional context in comments.

5 Comments

A nifty trick is also using the short circuit feature of JS! To avoid doing something like isTrue ? <div>Something</div> : null you can just do isTrue && <div>Something</div>
In addition, you can checkout the following article to find out about more conditional renderings in React apart from if else.
I want to handle condition in the loop like "data.map(item => ( <tr> <td> if(item.type == 'image'){ <image src="{image.src}"> } else{ { item} } </td> </tr> )) " something like this
why did they do it this way? Why rewrite javascript? I was taught in programming 101 to not use ternary operators, when I can use 'if'. One is much more readable.
@johnk It's in fact the opposite - unlike Vue and Angular, React is mostly "just javascript". The underlying reason for the above is JSX is transpiled down to function calls. <div>stuff</div> becomes createElement('div', 'stuff') and in js you can't have statements inside function calls: createElement('div', if(true) { return 'stuff' } else { return 'other' }). But in JS you can have expressions like the ternary operator in function calls: createElement('div', true ? 'stuff' : 'other')
214

There actually is a way to do exactly what OP is asking. Just render and call an anonymous function like so:

render () {
  return (
    <div>
      {(() => {
        if (someCase) {
          return (
            <div>someCase</div>
          )
        } else if (otherCase) {
          return (
            <div>otherCase</div>
          )
        } else {
          return (
            <div>catch all</div>
          )
        }
      })()}
    </div>
  )
}

1 Comment

Answer is really nice. Just makes me ask the question about React in general, why it is like early days of PHP?
58

Four ways of conditional rendering

(In functional component's return statement or class component's render function's return statement)

 

Ternary operator

 

return (
    <div>     
        {
            'a'==='a' ? <p>Hi</p> : <p>Bye</p>
        } 
    </div>
)

Note: Only if the condition 'a'==='a' is true, <p>Hi</p> will be rendered in the screen. Otherwise, <p>Bye</p> will be rendered on the screen.

 

Logical operator

 

AND &&

return (
    <div>     
        {
            'a'==='a' && <p>Hi</p>
        } 
    </div>
)

Note: Only if the condition 'a'==='a' is true, <p>Hi</p> will be rendered in the screen.

 

OR ||

export default function LogicalOperatorExample({name, labelText}) {
    
  return (
    <div>       
         {labelText || name}      
    </div>
  )
}

Note: If labelText and name both props are passed into this component, then labelText will be rendered in the screen. But if only one of them (name or labelText ) is passed as prop, then that passed prop will be rendered in the screen.

 

if, else, else if

 

return ( 
        <div>     
            {
                (() => {
                    if('a'==='b') {
                            return (
                                <p>Hi</p>
                            )
                        } else if ('b'==='b') {
                            return (
                            <p>Hello</p>
                            )
                        } else {
                            return (
                                <p>Bye</p>
                            )
                        }
                })()  
            }  
        </div>  
    )

Note: Have to use an anonymous functions (also need to immediately invoke the function )

 

Switch statement

 

return ( 
    <div>     
        {
            (() => {
                switch(true) {
                        
                    case('a'==='b'): {
                            return (
                                <p>Hello</p>
                            )
                        }
                    break;
                        
                    case('a'==='a'): {
                        return (
                            <p>Hi</p>
                        )
                    }
                    break;
                    
                    default: {
                            return (
                                <p>Bye</p>
                            )
                        }
                    break;
                    }
            })()  
        }  
    </div>  
)

Note: Have to use an anonymous functions (also need to immediately invoke the function)

3 Comments

which is better for performance switch or if elseif
The performance difference between them is negligible, the choice between them often comes down to personal preference and readability.
I find your response very helpful as you showed us lots of different ways. Thanks for your contribution.
27

For only if:

{condition1 && 
(<div> condition1 true </div>)}

For if and else:

{condition1 ? 
(<div> condition1 true </div>)
:(<div> condition1 false </div>)}

For if, else if, and else:

{condition1 ? 
(<div>condition1 true</div>)
:(condition2) ? 
(<div>condition2 true</div>)
:(<div>both conditions false</div>)}

Comments

20

You can render anything using the conditional statement like if, else :

 render() {
    const price = this.state.price;
    let comp;

    if (price) {

      comp = <h1>Block for getting started with {this.state.price}</h1>

    } else {

      comp = <h1>Block for getting started.</h1>

    }

    return (
      <div>
        <div className="gettingStart">
          {comp}
        </div>
      </div>
    );
  }

Comments

17

Type 1: If statement style

{props.hasImage &&

  <MyImage />

}


Type 2: If else statement style

   {props.hasImage ?

      <MyImage /> :

      <OtherElement/>

    }

Comments

6

You should Remember about TERNARY operator

:

so your code will be like this,

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // note: code does not work here
            { 
               this.props.hasImage ?  // if has image
               <MyImage />            // return My image tag 
               :
               <OtherElement/>        // otherwise return other element  

             }
        </div>
    )
}

Comments

6

The shorthand for an if else structure works as expected in JSX

this.props.hasImage ? <MyImage /> : <SomeotherElement>

You can find other options on this blogpost of DevNacho, but it's more common to do it with the shorthand. If you need to have a bigger if clause you should write a function that returns or component A or component B.

for example:

this.setState({overlayHovered: true});

renderComponentByState({overlayHovered}){
    if(overlayHovered) {
        return <OverlayHoveredComponent />
    }else{
        return <OverlayNotHoveredComponent />
    }
}

You can destructure your overlayHovered from this.state if you give it as parameter. Then execute that function in your render() method:

renderComponentByState(this.state)

Comments

5

If you need more than one condition, so you can try this out

https://www.npmjs.com/package/react-if-elseif-else-render

import { If, Then, ElseIf, Else } from 'react-if-elseif-else-render';

class Example extends Component {

  render() {
    var i = 3; // it will render '<p>Else</p>'
    return (
      <If condition={i == 1}>
        <Then>
          <p>Then: 1</p>
        </Then>
        <ElseIf condition={i == 2}>
          <p>ElseIf: 2</p>
        </ElseIf>
        <Else>
          <p>Else</p>
        </Else>
      </If>
    );
  }
}

Comments

5

You can also use conditional (ternary) operator inside conditional operator in case you have 2 different dependencies.

{
(launch_success)
  ?
  <span className="bg-green-100">
    Success
  </span>
  :
  (upcoming)
    ?
    <span className="bg-teal-100">
      Upcoming
    </span>
    :
    <span className="bg-red-100">
      Failed
    </span>
}

Comments

4

If you want a condition to show elements, you can use something like this.

renderButton() {
    if (this.state.loading) {
        return <Spinner size="small" spinnerStyle={styles.spinnerStyle} />;
    }

    return (
        <Button onPress={this.onButtonPress.bind(this)}>
            Log In
        </Button>
    );
}

Then call the helping method inside render function.

<View style={styles.buttonStyle}>
      {this.renderButton()}
</View>

Or you can use another way of condition inside return.

{this.props.hasImage ? <element1> : <element2>}

Comments

3

Lot's of great answers, however I haven't seen the use of an object for mapping to different views

const LOGS = {
  info: <Info />,
  warning: <Warning />,
  error: <Error />,
};
 
const Notification = ({ status }) => <div>{LOGS[status]}</div>

Comments

3

I used a ternary operator and it's working fine for me.

{item.lotNum == null ? ('PDF'):(item.lotNum)}

1 Comment

Unexpected token, expected "," ....for ternary operator based conditioning
3

None of the answers mention the short-circuit method

{this.props.hasImage && <MyImage />}

Granted you cannot use it if you want to render something on the else logic. I learned about this on react by example

on a deeper scan I do see a comment by @ZekeDroid, but I will drop this as an answer since it could be useful.

Comments

3

Shorthand for if then

 { condition ? <Element1/> : null }

1 Comment

{condition && <Element1/>} do the same and it's more cleaner.
3

Yes you can use condition in JSX render. You can read more here.

Syntax:

condition ? exprIfTrue : exprIfFalse

Condition statement must be this way below, here an example:

return (
    <div>
      {condition  ? (
        //do some actions if condition is true
      ) : (
        //do some actions if condition is false
      )}
    </div>
)

Comments

2

May be I'm too late here. But I hope this would help someone. First separate those two elements.

renderLogout(){
<div>
   <LogoutButton onClick={this.handleLogoutClick} />
<div>
}

renderLogin(){
<div>
   <LoginButton onClick={this.handleLoginClick} />
<div>
}

Then you can call these functions from render function using if else statement.

render(){
if(this.state.result){
  return this.renderResult();
}else{
  return this.renderQuiz();
}}

This works for me. :)

Comments

2

Try going with Switch case or ternary operator

render(){
    return (
        <div>
            <Element1/>
            <Element2/>
            // updated code works here
            {(() => {
                        switch (this.props.hasImage) {
                            case (this.props.hasImage):
                                return <MyImage />;
                            default:
                                return (
                                   <OtherElement/>; 
                                );
                        }
                    })()}
        </div>
    )
}

This worked for me and should work for you else. Try Ternary Operator

Comments

2

If you want to use If, else if, and else then use this method

           {this.state.value === 0 ? (
                <Component1 />
            ) : this.state.value === 1 ? (
              <Component2 />
            ) : (
              <Component3 />
            )}

Comments

2

You can introduce separate method that will return div elements and call it inside of return. I use this case for example for error rendering depends on status, such as:

const renderError = () => {
    if (condition)
        return ....;
    else if (condition)
        return ....;
    else if (condition)
        return ....;
    else
        return ....;
}

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

Comments

1

I don't think i saw this solution for an inline else if rendering where you have more that 2 conditions so i'm sharing it :

{variable == 0 ?
  <Element1/>
:variable == 1 ?
  <Element2/>
:variable == 2 ?
  <Element3/>
:
  <Element4/>
}

Comments

0

I found that a solution that I thought was better than having an if-else. Instead have 2 return statements. See example:

render() {
    const isLoggedIn = this.state.isLoggedIn;

    if (isLoggedIn) {
        return <LogoutButton onClick={this.handleLogoutClick} />
    }

    // This will never occur if the user is logged in as the function is returned before that.
    return <LoginButton onClick={this.handleLoginClick} />
}

This is less cluttered than having an if-else or ternary operator in your return statement.

Comments

0

You can write If statement component too. Here is what I use in my project.

components/IfStatement.tsx

import React from 'react'

const defaultProps = {
    condition: undefined,
}

interface IfProps {
    children: React.ReactNode
    condition: any
}

interface StaticComponents {
    Then: React.FC<{ children: any }>
    Else: React.FC<{ children: any }>
}

export function If({ children, condition }: IfProps): any & StaticComponents {
    if (React.Children.count(children) === 1) {
        return condition ? children : null
    }

    return React.Children.map(children as any, (element: React.ReactElement) => {
        const { type: Component }: any = element

        if (condition) {
            if (Component.type === 'then') {
                return element
            }
        } else if (Component.type === 'else') {
            return element
        }

        return null
    })
}

If.defaultProps = defaultProps

export function Then({ children }: { children: any }) {
    return children
}

Then.type = 'then'

export function Else({ children }: { children: any }) {
    return children
}

Else.type = 'else'

If.Then = Then as React.FC<{ children: any }>
If.Else = Else as React.FC<{ children: any }>

export default If

Usage example:

<If condition={true}>
   <If.Then>
        <div>TRUE</div>
   </If.Then>
   <If.Else>
        <div>NOT TRUE</div>
   </If.Else>
</If>

Comments

0

It may be late to answer this question, but I think people still face this issue. Recently, I just created a library to solve this issue. Please give it a try.

Here is the link. https://www.npmjs.com/package/condition-switch

The following code can handle this issue with this library.


return (
  <div>
    {condSwitch(
      [
        [condition === 'A', () => <div>Condition A</div>],
        [condition === 'B', () => <div>Condition B</div>],
        [condition === 'C', () => <div>Condition C</div>],
      ],
      <div>Default Condition</div>,
    )}
  </div>
);

Comments

-1

Below Code you can use for If condition on react in side return

                                    {(() => {if (true) {return ( <div><Form>
                                        <Form.Group as={Row} style={{ marginLeft: '15px', marginRight: '15px', marginBlock: '0px' }} >
                                            <Form.Label className="summary-smmdfont" style={{ flex: '1 0 auto', marginBlock: '0px' }}>   uyt</Form.Label>
                                            <Form.Label className="summary-smmdfont"style={{ textAlignLast: 'Right', flex: '1 0 auto', marginBlock: '0px' }}>
                                                09</Form.Label>
                                        </Form.Group>
                                        </Form>

                                    </div>);
                    }})()}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.