69

I'm using react and I'm trying to display this error message if this.state.message === 'failed'. But I'm really not sure why this ternary operation isn't working. What am I doing wrong here?

render() {
    ...
    <div className="row">
        return (this.state.message === 'failed') ? ( =>{" "}
        {
            <div className="alert alert-danger" role="alert">
                Something went wrong
            </div>
        }
        )() : false; }
    </div>
}

Right now its just displaying return (this.state.message === 'failed') ? ( => in the html

Guilherme Samuel
  • 459
  • 6
  • 11
Modelesq
  • 5,192
  • 20
  • 61
  • 88
  • That doesn't look like valid syntax... I'd use a regular `if` statement there. Why are you returning `false` anyway? – elclanrs Jun 28 '16 at 19:27
  • Did you try to wrap it in `{}` ? Like.. `{ this.state.message === 'failed' ?
    Things
    : null }`
    – Mark C. Jun 28 '16 at 19:41

8 Answers8

130

I currently like to format my ternaries like this in react:

render () {
  return (
    <div className="row">
      { //Check if message failed
        (this.state.message === 'failed')
          ? <div> Something went wrong </div> 
          : <div> Everything in the world is fine </div> 
      }
    </div>
  );
}

You are correct that IIFEs can be used within a render statement as well as ternary expressions. Using a normal if .. else statement is valid, but the render function's return statement can only contain expressions so you would have to do those elsewhere..

Gosha A
  • 4,520
  • 1
  • 25
  • 33
Nathan
  • 1,455
  • 1
  • 10
  • 7
  • 3
    Perhaps a good [article](https://www.robinwieruch.de/conditional-rendering-react/) to learn about React's conditional renderings. – Robin Wieruch Jul 19 '17 at 18:19
7

The syntax for ternary is condition ? if : else. To be safe, you can always wrap the entire ternary statement inside parenthesis. JSX elements are also wrapped in parenthesis. The fat arrow in an arrow function is always preceeded by two parenthesis (for the arguments) - but you don't need any functions here anyway. So given all of that, there are a couple of syntax errors in your code. Here's a working solution:

render() {
  return (this.state.message === 'failed' ? (
   <div className="alert alert-danger" role="alert">
     Something went wrong
   </div>
  ) : null);
}

Edit: if this is inside other markup, then you don't need to call render again. You can just use curly braces for interpolation.

render() {
  return (
    <div className="row">
      {this.state.message === 'failed' ? (
       <div className="alert alert-danger" role="alert">
         Something went wrong
       </div>
      ) : null}
    </div>
  );
}
Matis Lepik
  • 1,140
  • 2
  • 9
  • 18
6

The accepted answer by @Nathan and other similar answers are correct. But it's worth noting that the result for ? and the result for : must each be a single element or wrapped in a single element (or the result may be null | undefined, either of which qualifies as a single element). In the example below, the result for ? will work but the result for : will fail....

return (
  {this.state.message === 'failed' ? (
      <div>
        <row>three elements wrapped</row>
        <row>inside</row>
        <row>another element work.</row>
      </div>
    ) : (
      <row>html like</row>
      <row>haiku</row>
      <row>must follow rules of structure.</row>
    )
  }
)
Kenigmatic
  • 448
  • 6
  • 16
3

You should try this:

render () {
    return (
        <div className="row">
            { (this.state.message === 'failed') ?
                 <div className="alert alert-danger" role="alert">
                     Something went wrong
                 </div> :
                 <span> Everything in the world is fine </span> }
        </div>
    );
}
Elod Szopos
  • 3,475
  • 21
  • 32
  • This still shows `return ( Everything in the world is fine );` on the page when rendered :\ – Modelesq Jun 28 '16 at 19:33
  • 1
    Updated to your latest edit in your question. If you want nothing returned, simply replace the `` with `undefined` or `null`. – Elod Szopos Jun 28 '16 at 19:42
3

Given the above answers, you can also directly return a ternary expression from return() in your render() like this

return condition? this.function1(): this.function2();

and inside function1() and function2() you can return your views.

Aayushi
  • 1,736
  • 1
  • 26
  • 48
2

For using variable inside ternary use brackets again

render() {
  return(
    <div className='searchbox'>
     {this.state.var ? <div className='warning'>{this.state.var}</div> : ''}
    </div>
  )
}
Nikolay Podolnyy
  • 931
  • 10
  • 19
2

Please remember that the ternary expression should be wrapped in a Fragment or div, if it's not wrapped it'll throw a compilation error

return (
        <Fragment>
            {fetching ? <Loading></Loading> : <p>Fetched</p>}
        </Fragment>
);
Ezequiel Falcon
  • 316
  • 2
  • 5
0

Another answer using React shorthand fragments (like <>...</>) and components (functions and not classes):

return (
        <>
            {fetching ? <Loading></Loading> : <p>Fetched</p>}
        </>
);