Non
Non

Reputation: 8589

How to display and hide elements correctly in Reactjs

I have all this component here which for a Chat app, there are 2 views, 1 for dealer and another for players

  render () {
    let messages = this.props.chatMessages.map((message) => {
      return <ChatItem info={message.info} me={message.me} player={message.player} message={message.message} />;
    });

    let chatForm, hr, dealerMode, playerMode;

    if (this.props.mode === 'player') {
      hr = <hr />;
      chatForm = <ChatForm onAddMessage={this.addMessage} />;
      playerMode = <ul className="Chat__player--messages" ref="messages">{messages}</ul>;
    }

    if (this.props.mode === 'dealer') {
      dealerMode = <ul className="Chat__dealer--messages" ref="messages">{messages}</ul>;
    }

    return <div className="Chat">
      <div className="Chat__player">
        {playerMode}
        {hr}
        {chatForm}
      </div>
      <div className="Chat__dealer">
        {dealerMode}
      </div>
    </div>;
  }

as I have it so far, works but not properly. When you are on the dealer view, you can see a little line for this <div className="Chat__player"> even nothing comes up.

I tried by doing

    return <div className="Chat">
      if (this.props.mode === 'player') {
        <div className="Chat__player">
           {playerMode}
           {hr}
           {chatForm}
        </div>
      }
      <div className="Chat__dealer">
        {dealerMode}
      </div>
    </div>;

but all I get is that if statement printed in the browser.

Upvotes: 1

Views: 102

Answers (2)

Chris Martin
Chris Martin

Reputation: 30736

There's a good example of a conditional element tucked away on the False in JSX documentation:

<div>{x > 1 && 'You have more than one item'}</div>

Adapted to your example:

return <div className="Chat">
    {this.props.mode === 'player' &&
        <div className="Chat__player">
            {playerMode}
            {hr}
            {chatForm}
        </div>}
    <div className="Chat__dealer">
        {dealerMode}
    </div>
</div>;

Upvotes: 2

franky
franky

Reputation: 1333

Since <div className="Chat__player"> will always show you want to not print it at all in the dealer situation (you had the right idea in your second example but it wasn't valid JSX). Here are two possible ways you can do it (out of many)

Modifying your second example to use ternary:

return <div className="Chat">
  {this.props.mode === 'player' ? 
    <div className="Chat__player">
      {playerMode}
      {hr}
      {chatForm}
    </div> : null}

  {this.props.mode === 'dealer' ? 
    <div className="Chat__player">
      {dealerMode}
    </div> : null}
</div>;

Or without ternary:

let display;
let messagesList = <ul className="Chat__dealer--messages" ref="messages">{messages}</ul>;

if (this.props.mode === 'player') {
  display = <div className="Chat__player">
    {messagesList}
    <hr />
    <ChatForm onAddMessage={this.addMessage} />
  </div>
}

if (this.props.mode === 'dealer') {
  display = <div className="Chat__dealer">
    {messagesList}
  </div>
}

return <div className="Chat">
  {display}
</div>;

Upvotes: 2

Related Questions