Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add logical if statement when rendering React components?

Tags:

reactjs

if I have code that looks like this...

var Lounge = React.createClass({displayName: "Lounge",
  render: function() {
    return (
            React.createElement("a", {href:"/lounge/detail/" + this.props.id +  "/"},
            React.createElement("div", {className: "lounge"},
            React.createElement("h2", {className: "loungeAuthor"},
              this.props.author.name
            ),
            React.createElement("p", {className: "loungeArticle"},
              this.props.article
            ),
            React.createElement("img", {className: "loungeImage", src: this.props.image})
          )
        )
    );
  }
});

I need to do a logical if check to only render the "img" component if the image data exists. Does anybody know the best way to go about this using React?

like image 538
Chris Hawkes Avatar asked Feb 01 '15 01:02

Chris Hawkes


People also ask

How do you write if condition in JSX?

We can embed any JavaScript expression in JSX by wrapping it in curly braces. But only expressions not statements, means directly we can not put any statement (if-else/switch/for) inside JSX.

How do you conditionally render functional components in React?

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if or the conditional operator to create elements representing the current state, and let React update the UI to match them. This example renders a different greeting depending on the value of isLoggedIn prop.

Should you use ternary or && operator to conditionally render React components?

Conditional Rendering in React: &&That's your way to go when you want to return nothing or an element inside JSX. It's also called short-circuit evaluation which makes it even more concise than a ternary operator.


5 Answers

If you want to do it inline, you can do:

{this.props.image && <img className="loungeImage" src={this.props.image}/>}

this.props.image && React.createElement("img", {className: "loungeImage", src: this.props.image})

If the value you want to check is falsy but would result in something being rendered by React, like an empty string, you might want to convert it to its boolean equivalent in the check by using !!:

{!!this.props.image && <img className="loungeImage" src={this.props.image}/>}

!!this.props.image && React.createElement("img", {className: "loungeImage", src: this.props.image})
like image 157
Jonny Buchanan Avatar answered Oct 31 '22 21:10

Jonny Buchanan


Keeping this logic inline as well as using JSX may help with readability

import React from 'react';
import PropTypes from 'prop-types';
import s from './Lounge.css'; // See CSS Modules

// Stateless functional component (since there is no state)
function Lounge({ id, article, author, imageUrl }) {
  return (
    <a href={`/lounge/detail/${id}/`}>
      <span className={s.lounge}>
        <span className={s.author}>{author.name}</span>
        <span className={s.article}>{article}</span>
        {imageUrl && <img className={s.image} src={imageUrl} />} // <==
      </span>
    </a>
  );
}

// Props validation
Lounge.propTypes = {
  id: PropTypes.number.isRequired,
  article: PropTypes.string.isRequired,
  imageUrl: PropTypes.string,
  author: PropTypes.shape({
    name: PropTypes.string.isRequired
  }).isRequired
};

export default Lounge;
like image 37
Konstantin Tarkus Avatar answered Oct 31 '22 21:10

Konstantin Tarkus


You can use React if component:

var Node = require('react-if-comp');

var Lounge = React.createClass({
    displayName: 'Lounge',
    render: function() {
        return (
            <a href={'/lounge/detail/' + this.props.id + '/'}>
                <div className='lounge'>
                    <h2 className='loungeAuthor'>{author.name}</h2>
                    <p className='loungeArticle'>{article}</p>
                    <Node if={this.props.image}
                        then={<img className='loungeImage'
                        src={this.props.image} />} />
                </div>
            </a>
        );
    }
});
like image 31
Gordon Freeman Avatar answered Oct 31 '22 21:10

Gordon Freeman


Using JSX + IIFE (Immediately-Invoked function) can come pretty handy and explicit:

{(() => {
  if (isEmpty(routine.queries)) {
    return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
  } else if (this.state.configured) {
    return <DeviceList devices={devices} routine={routine} configure={() => this.setState({configured: false})}/>
  } else {
    return <Grid devices={devices} routine={routine} configure={() => this.setState({configured: true})}/>
  }
})()}
like image 42
jsdario Avatar answered Oct 31 '22 22:10

jsdario


Okay so this may be clear to a lot of people, for some reason I didn't see it, then again I'm quickly scanning through the documents and I'm not using JSX (really don't like it)

Therefore the JavaScript way of adding logical if checks when rendering react components would be done like this. (keep in mind undefined works just fine, so assuming the if statement is not hit it will still render just fine)

var Lounge = React.createClass({displayName: "Lounge",
  render: function() {
    if (this.props.image != "") {
       var imageElement = React.createElement("img", {className: "loungeImage", src: this.props.image});
    }
    return (
            React.createElement("a", {href:"/lounge/detail/" + this.props.id +  "/"},
            React.createElement("div", {className: "lounge"},
            React.createElement("h2", {className: "loungeAuthor"},
              this.props.author.name
            ),
            React.createElement("p", {className: "loungeArticle"},
              this.props.article
            ),
            imageElement
          )
        )
    );
  }
});
like image 45
Chris Hawkes Avatar answered Oct 31 '22 22:10

Chris Hawkes