60

I'm trying to render a div on the same page when the user clicks on a link.

My HTML page:

<div class="stores">
  <h1>Stores</h1>
  <ul class="stores">
    <li><a href="#" onClick={this.onClick} >Store A</a></li>
    <li>Store B</li>
    <li>Store C</li>
  </ul>
</div>

My components/store.js.jsx:

var Store = React.createClass({
  getInitialState: function() {
    return { showStore: false };
  },
  onClick: function() {
      this.setState({ showStore: true });
  },
  render: function() {
  return(
    <div className="row account stores" style={{display: { this.state.showStore ? 'block' : 'none'} }}>
      <div>a lot more divs</div>
        </div>
    );
  }
});

But I get a:

SyntaxError: unknown: Unexpected token

For this line:

style={{display: { this.state.showStore ? 'block' : 'none'} }}

How can I nest conditionally inside a style?

totymedli
  • 29,531
  • 22
  • 131
  • 165
StandardNerd
  • 4,093
  • 9
  • 46
  • 77

3 Answers3

113

This is due to incorrect usage of the ternary operator. See documentation here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

You should not wrap it with {} as you have done.

Try the following:

style={{display: this.state.showStore ? 'block' : 'none' }}
ctrlplusb
  • 12,847
  • 6
  • 55
  • 57
  • 12
    I can't find in the React documentation, but if you set a style attribute to `null` React doesn't add the attribute to the DOM node at all. So the following only set `display: none` or nothing based on the condition. `style={{ display: isHidden ? 'none' : null }}` This is useful if you specify display value in css - for example some form of flexbox - and you don't want to hardcode this value in javascript. – wiktor Dec 15 '16 at 23:08
  • @wiktor you might have read this in the [classname library](https://www.npmjs.com/package/classnames) – cquezel Aug 08 '18 at 19:55
  • @cquezel Possible. Unfortunately, I did not remember what was the original source of the truth. :( I just use it. – wiktor Aug 09 '18 at 11:30
7

You can also conditionally create the element via

   { 
     this.state.showStore 
     ? <div className="row account stores">
        <div>a lot more divs</div>
       </div> 
     : null 
   }
00500005
  • 3,727
  • 3
  • 31
  • 38
7

You can also change a classname and style in CSS.

// outside render
const NORMAL = "row account stores"
const HIDDEN = NORMAL + " hidden"

// In render
render: function() {
  return(
    <div className={this.state.showStore ? NORMAL : HIDDEN}>
      <div>a lot more divs</div>
        </div>
  );
}

Note that it is generaly better to not use double curly braces {{ in render function as you are often creating a new object on every render execution. for example:

{display: true ? 'block' : 'none' } === {display: true ? 'block' : 'none' } // false

// outside render
const BLOCK = { display: 'block' }
const NONE= { display: 'none' }

// in render
{this.state.showStore ? BLOCK : NONE}
KvnG.
  • 658
  • 1
  • 7
  • 17
cquezel
  • 3,859
  • 1
  • 30
  • 32