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?
When creating a list in the UI from an array with JSX, you should add a key prop to each child and to any of its' children. React uses the key prop create a relationship between the component and the DOM element. The library uses this relationship to determine whether or not the component should be re-rendered.
Why do we use fragments in React? React fragments serve as a cleaner alternative to using unnecessary divs in our code. These fragments do not produce any extra elements in the DOM, which means that a fragment's child components will render without any wrapping DOM node.
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 /> </> )
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." ]; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With