577

I am trying to set up my React.js app so that it only renders if a variable I have set is true.

The way my render function is set up looks like:

render: function() {
    var text = this.state.submitted ? 'Thank you!  Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
    var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
    return (
    <div>

if(this.state.submitted==false) 
{

      <input type="email" className="input_field" onChange={this._updateInputValue} ref="email" value={this.state.email} />

      <ReactCSSTransitionGroup transitionName="example" transitionAppear={true}>
      <div className="button-row">
         <a href="#" className="button" onClick={this.saveAndContinue}>Request Invite</a>
     </div>
     </ReactCSSTransitionGroup>
}
   </div>
    )
  },

Basically, the important portion here is the if(this.state.submitted==false) portion (I want these div elements to show up when the submitted variable is set to false).

But when running this, I get the error in the question:

Uncaught Error: Parse Error: Line 38: Adjacent JSX elements must be wrapped in an enclosing tag

What is the issue here? And what can I use to make this work?

norbitrial
  • 14,716
  • 7
  • 32
  • 59
user1072337
  • 12,615
  • 37
  • 116
  • 195
  • 3
    http://stackoverflow.com/questions/25034994/how-to-correctly-wrap-few-td-tags-for-jsxtransformer The other people here are just telling you to use a parent element, but that may be unnecessary. This older version of your question has an interesting answer using arrays. – Meow May 11 '16 at 10:11

16 Answers16

777

You should put your component between an enclosing tag, Which means:

// WRONG!

return (  
    <Comp1 />
    <Comp2 />
)

Instead:

// Correct

return (
    <div>
       <Comp1 />
       <Comp2 />
    </div>
)

Edit: Per Joe Clay's comment about the Fragments API

// More Correct

return (
    <React.Fragment>
       <Comp1 />
       <Comp2 />
    </React.Fragment>
)

// Short syntax

return (
    <>
       <Comp1 />
       <Comp2 />
    </>
)
beaver
  • 523
  • 1
  • 9
  • 20
wdanxna
  • 10,699
  • 2
  • 23
  • 24
295

It is late to answer this question but I thought It will add to the explanation.

It is happening because any where in your code you are returning two elements simultaneously.

e.g

return(
    <div id="div1"></div>
    <div id="div1"></div>
  )

It should be wrapped in a parent element. e.g

 return(
      <div id="parent">
        <div id="div1"></div>
        <div id="div1"></div>
      </div>
      )

More Detailed Explanation

Your below jsx code get transformed

class App extends React.Component {
  render(){
    return (
      <div>
        <h1>Welcome to React</h1>
      </div>
    );
  }
}

into this

_createClass(App, [{
    key: 'render',
    value: function render() {
      return React.createElement(
        'div',
        null,
        React.createElement(
          'h1',
          null,
          'Welcome to React'
        )
      );
    }
  }]);

But if you do this

class App extends React.Component {
  render(){
    return (
        <h1>Welcome to React</h1>
        <div>Hi</div>
    );
  }
}

this gets converted into this (Just for illustration purpose, actually you will get error : Adjacent JSX elements must be wrapped in an enclosing tag)

_createClass(App, [{
    key: 'render',
    value: function render() {
      return React.createElement(
        'div',
        null,
       'Hi'
      ); 
    return React.createElement(
          'h1',
          null,
          'Welcome to React'
        )
    }
  }]);

In the above code you can see that you are trying to return twice from a method call, which is obviously wrong.

Edit- Latest changes in React 16 and own-wards:

If you do not want to add extra div to wrap around and want to return more than one child components you can go with React.Fragments.

React.Fragments (<React.Fragments>)are little bit faster and has less memory usage (no need to create an extra DOM node, less cluttered DOM tree).

e.g (In React 16.2.0)

render() {
  return (
    <>
       React fragments.
      <h2>A heading</h2>
      More React fragments.
      <h2>Another heading</h2>
      Even more React fragments.
    </>
  );
}

or

render() {
  return (
    <React.Fragments>
       React fragments.
      <h2>A heading</h2>
      More React fragments.
      <h2>Another heading</h2>
      Even more React fragments.
    </React.Fragments>
  );
}

or

render() {
 return [
  "Some text.",
  <h2 key="heading-1">A heading</h2>,
  "More text.",
  <h2 key="heading-2">Another heading</h2>,
  "Even more text."
 ];
}
Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
WitVault
  • 23,445
  • 19
  • 103
  • 133
122

React element has to return only one element. You'll have to wrap both of your tags with another element tag.

I can also see that your render function is not returning anything. This is how your component should look like:

var app = React.createClass({
    render () {
        /*React element can only return one element*/
        return (
             <div></div>
        )
    }
})

Also note that you can't use if statements inside of a returned element:

render: function() {
var text = this.state.submitted ? 'Thank you!  Expect a follow up at '+email+' soon!' : 'Enter your email to request early access:';
var style = this.state.submitted ? {"backgroundColor": "rgba(26, 188, 156, 0.4)"} : {};
    if(this.state.submitted==false) {
        return <YourJSX />
    } else {
        return <YourOtherJSX />
    }
},
Rob Bednark
  • 25,981
  • 23
  • 80
  • 125
Matan Gubkin
  • 3,019
  • 6
  • 25
  • 44
102

If you don't want to wrap it in another div as other answers have suggested, you can also wrap it in an array and it will work.

// Wrong!
return (  
   <Comp1 />
   <Comp2 />
)

It can be written as:

// Correct!
return (  
    [<Comp1 />,
    <Comp2 />]
)

Please note that the above will generate a warning: Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.

This can be fixed by adding a key attribute to the components, if manually adding these add it like:

return (  
    [<Comp1 key="0" />,
    <Comp2 key="1" />]
)

Here is some more information on keys:Composition vs Inheritance

Edgar
  • 6,022
  • 8
  • 33
  • 66
Neal
  • 3,119
  • 4
  • 27
  • 32
  • The "correct" way here warns: `Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'ContentContainer'.` – janhartmann May 18 '16 at 08:03
  • You can simply add a key to the components to avoid this warning. Check here http://facebook.github.io/react/docs/multiple-components.html#dynamic-children – Neal May 18 '16 at 09:34
  • 7
    I tried this and it gives me an error. A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object. – prasadmsvs May 26 '16 at 18:40
  • 3
    @prasadmsvs +1 invariant.js:39 Uncaught Invariant Violation: CommitFilter.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object. – Svetlana Ivanova Jun 04 '16 at 07:45
  • 1
    This is a great solution for times where you need/want to avoid a wrapper element! – bloudermilk Oct 28 '16 at 17:49
  • I still find it weird that react couldn't find a way to implement their framework without allowing multiple adjacent elements being returned from any given function. Makes for awkward coding at times, and I don't agree that wrapper elements are "fine". When coding vanilla html/js/css, they are hacks to get the desired behavior not otherwise possible and are not semantic html. – aaaaaa Dec 20 '16 at 03:44
  • 2
    @aaaaaa it is not possible because of the way the current React reconciler works. It is a stack and reconciliation is done recursively. In React 16 this is fixed, and you may now return an array. – natnai Mar 01 '17 at 12:57
  • @natnai - interesting. thanks much for giving me a direction on where to look to read further – aaaaaa Mar 01 '17 at 15:43
  • 1
    https://github.com/iamdustan/tiny-react-renderer is an excellent repository that every react developer should read. Once you do, it should become immediately apparent to you why the current implementation of react doesn't allow returning multiple children. – natnai Mar 01 '17 at 15:45
  • This is super helpful, especially when you're generating an Array of Components dynamically. You can use something like `arrayOfComponents = [];` and then `arrayOfComponents.push( );` to append to it. Thanks. – Joshua Pinter Mar 14 '17 at 01:37
  • Perhaps I'm missing something, but I really don't understand why this got 41 up-votes. A component must return **one** react component. Returning an array is not a valid return type - the error even says so: *A valid React element (or null) must be returned. You may have returned undefined, **an array** or some other invalid object.*. The only place I know you can do this is ***within*** a react-component... returning an array is a feature for React v16. Downvoting this because it seems incorrect to me - I'll happily undo if I'm proved wrong. – Chris Jun 21 '17 at 13:29
  • @Chris Nothing in this solution says anything about rendering a component. This solution works perfectly well for encapsulating children elements in an external function for use inside of an existing outer element. In fact it is the only viable solution in some cases (e.g. ,
  • etc.)
  • – pscl Sep 08 '17 at 19:59
  • @user1628461, the whole question is about an error which can only be generated from components. – Chris Sep 08 '17 at 20:02
  • 1
    Adjacent tags in JSX are parsed into an array - perfectly normal. The OP is only getting an error because his if() block breaks up the JSX parser causing it to expect a single outer element. In fact, encapsulating the if() block in a helper function returning an array is the more elegant way of addressing the question. This works in React <=15. React 16 simply eliminates the need for boilerplate square brackets and commas. – pscl Sep 09 '17 at 05:28
  • @pscl, I don't quite follow. Are you saying you can return arrays from the render method in React <=15? – Chris Oct 27 '17 at 07:37
  • 1
    Very helpful for me in my TABLE situation, where wrapping els in a div isn't allowed. – Scott Dec 13 '17 at 17:22