13

I'm trying to return two links if the user is not logged in. Something like this:

<Nav>
    {if(this.state.user) {
        <NavItem onClick={this.logout}>Log out</NavItem>
    } else {
        <NavItem onClick={this.login}>Log in</NavItem>
        <NavItem onClick={this.register}>Register</NavItem>
    }
    }
</Nav>

I know I can do this with a ternary operator:

<Nav>
    {this.state.user ?
        <NavItem onClick={this.logout}>Log out</NavItem>
        :
        <NavItem onClick={this.login}>Log in</NavItem>
    }
</Nav>

The problem is I want to render the two NavItems. I saw I can do it with a function, but when I try to do it in a function like this:

myFunction(){
    return(
        <NavItem onClick={this.login}>Zaloguj się</NavItem>
        <NavItem onClick={this.login}>Zaloguj się</NavItem>
    )
}

It tells me that the second element is unreachable and breaks. So how can I return two elements? Stringifying the code doesn't help

Alex Ironside
  • 4,658
  • 11
  • 59
  • 119

4 Answers4

14

If you are using React v16.2.0 and above you can use the shorter version of Fragments

<>
 <NavItem onClick={this.login}>Zaloguj się</NavItem>
 <NavItem onClick={this.login}>Zaloguj się</NavItem>
</>

If you are using a version below React v16 you can only return one element in jsx, so you have to wrap your elements inside one:

<div>
 <NavItem onClick={this.login}>Zaloguj się</NavItem>
 <NavItem onClick={this.login}>Zaloguj się</NavItem>
</div>

If you are using React v16 and abose you can use Fragments

import React, { Fragment } from 'react';

...
...

    <Fragment>
     <NavItem onClick={this.login}>Zaloguj się</NavItem>
     <NavItem onClick={this.login}>Zaloguj się</NavItem>
    <Fragment/>

You could also return an Array of Elements as announced here:

 return [
    <NavItem key="1" onClick={this.login}>Zaloguj się</NavItem>,
    <NavItem key="2" onClick={this.login}>Zaloguj się</NavItem>
  ];

Depending on your environment you might not be able to use all of these solutions: support for fragments

Kevin Amiranoff
  • 13,440
  • 11
  • 59
  • 90
7

In the lastest react version you can wrap them in an empty fragment:

<>
  <NavItem onClick={this.login}>Zaloguj się</NavItem>
  <NavItem onClick={this.login}>Zaloguj się</NavItem>
</>
Joel Harkes
  • 10,975
  • 3
  • 46
  • 65
5

You need to wrap it around something, like <div> or <React.Fragment> (v16):

<React.Fragment>
  <NavItem onClick={this.login}>Log in</NavItem>
  <NavItem onClick={this.register}>Register</NavItem>
</React.Fragment>

You must use the ternary operators instead of if statements to directly render the elements in JSX.

Roy Wang
  • 11,112
  • 2
  • 21
  • 42
2

You can use Fragment in ReactJS which is available in React 16.

which lets you group a list of children without adding extra nodes to the DOM.

You can import fragment like below ,

import React, {Fragment} from 'react';
  To render:


  <Fragment>
   <ChildA />
   <ChildB />
   <ChildC />
 </Fragment>

By using Fragment, you can avoid extra html element such div being rendered.

For more info, you can refer https://reactjs.org/docs/fragments.html

Johnson Samuel
  • 2,046
  • 2
  • 18
  • 29