ChatGPT解决这个技术问题 Extra ChatGPT

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

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?

stackoverflow.com/questions/25034994/… 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.

b
beaver

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 />
    </>
)

What if I'm printing 2 rows together in a table. How can I wrap ?
@Jose you can use the Fragments API as shown in the answer, they don't produce any extra DOM elements.
K
Kevin Workman

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."
 ];
}

R
Rob Bednark

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 />
    }
},

this doesn't address the issue with the "if"; If I remove the "if" within the render function, it works fine.
note that you can't use if statments inside of a retuned element. look at my updated answer
S
Silicum Silium

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


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 +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.
This is a great solution for times where you need/want to avoid a wrapper element!
@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.
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.
C
Chris

The problem

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

This means that you are trying to return multiple sibling JSX elements in an incorrect manner. Remember that you are not writing HTML, but JSX! Your code is transpiled from JSX into JavaScript. For example:

render() {
  return (<p>foo bar</p>);
}

will be transpiled into:

render() {
  return React.createElement("p", null, "foo bar");
}

Unless you are new to programming in general, you already know that functions/methods (of any language) take any number of parameters but always only return one value. Given that, you can probably see that a problem arises when trying to return multiple sibling components based on how createElement() works; it only takes parameters for one element and returns that. Hence we cannot return multiple elements from one function call.

So if you've ever wondered why this works...

render() {
  return (
    <div>
      <p>foo</p>
      <p>bar</p>
      <p>baz</p>
    </div>
  );
}

but not this...

render() {
  return (
    <p>foo</p>
    <p>bar</p>
    <p>baz</p>
  );
}

it's because in the first snippet, both <p>-elements are part of children of the <div>-element. When they are part of children then we can express an unlimited number of sibling elements. Take a look how this would transpile:

render() {
  return React.createElement(
    "div",
    null,
    React.createElement("p", null, "foo"),
    React.createElement("p", null, "bar"),
    React.createElement("p", null, "baz"),
  );
}

Solutions

Depending on which version of React you are running, you do have a few options to address this:

Use fragments (React v16.2+ only!) As of React v16.2, React has support for Fragments which is a node-less component that returns its children directly. Returning the children in an array (see below) has some drawbacks: Children in an array must be separated by commas. Children in an array must have a key to prevent React’s key warning. Strings must be wrapped in quotes. These are eliminated from the use of fragments. Here's an example of children wrapped in a fragment: render() { return ( <> ); } which de-sugars into: render() { return ( ); } Note that the first snippet requires Babel v7.0 or above.

Children in an array must be separated by commas.

Children in an array must have a key to prevent React’s key warning.

Strings must be wrapped in quotes.

Return an array (React v16.0+ only!) As of React v16, React Components can return arrays. This is unlike earlier versions of React where you were forced to wrap all sibling components in a parent component. In other words, you can now do: render() { return [

foo

,

bar

]; } this transpiles into: return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")]; Note that the above returns an array. Arrays are valid React Elements since React version 16 and later. For earlier versions of React, arrays are not valid return objects! Also note that the following is invalid (you must return an array): render() { return (

foo

bar

); }

Wrap the elements in a parent element The other solution involves creating a parent component which wraps the sibling components in its children. This is by far the most common way to address this issue, and works in all versions of React. render() { return (

foo

bar

); } Note: Take a look again at the top of this answer for more details and how this transpiles.


@Grievoushead, not for components, no. Only for children.
on React v16.4 the first example does not work using: <>, only <React.Fragment> :(
@vsync the support for that syntax varies on your building environment. Not sure if babel supports it yet, and if so, which version.
@Chris - Thanks. I tried it on Codepen with the native Babel checkbox toggled
M
Morris S

React 16.0.0 we can return multiple components from render as an array.

return ([
    <Comp1 />,
    <Comp2 />
]);

React 16.2.0 > we can return multiple components from render in a Fragment tag. Fragment

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

React 16.2.0 > you can use this shorthand syntax. (some older tooling versions don’t support it so you might want to explicitly write <Fragment> until the tooling catches up.)

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

You forgot a , between the components. It's an array so you need to separate each element within it.
There's no <Fragment>, it's <React.Fragment>. says so in your own link
If you are destructuring import React { Fragment } from 'react'; then you use it like this <Fragment >
r
ronak ganatra

If you do not wrap your component then you can write it as mentioned below method.

Instead of:

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

you can write this:

return[(
 <Comp1 />
),
(
<Comp2 />
) ];

S
Shanteshwar Inde

it's very simple we can use a parent element div to wrap all the element or we can use the Higher Order Component( HOC's ) concept i.e very useful for react js applications

render() {
  return (
    <div>
      <div>foo</div>
      <div>bar</div>
    </div>
  );
}

or another best way is HOC its very simple not very complicated just add a file hoc.js in your project and simply add these codes

const aux = (props) => props.children;
export default aux;

now import hoc.js file where you want to use, now instead of wrapping with div element we can wrap with hoc.

import React, { Component } from 'react';
import Hoc from '../../../hoc';

    render() {
      return (
    <Hoc>
        <div>foo</div>
        <div>bar</div>
    </Hoc>
      );
    }

While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value.Read this.
The functionality that you are talking about, i.e called HOC in reactjs. means props.children
K
Khandelwal-manik

There is a rule in react that a JSX expression must have exactly one outermost element.

wrong

const para = (
    <p></p>
    <p></p>
);

correct

const para = (
    <div>
        <p></p>
        <p></p>
    </div>
);

J
JJJ

React 16 gets your return as an array so it should be wrapped by one element like div.

Wrong Approach

render(){
    return(
    <input type="text" value="" onChange={this.handleChange} />

     <button className="btn btn-primary" onClick=   {()=>this.addTodo(this.state.value)}>Submit</button>

    );
}

Right Approach (All elements in one div or other element you are using)

render(){
    return(
        <div>
            <input type="text" value="" onChange={this.handleChange} />

            <button className="btn btn-primary" onClick={()=>this.addTodo(this.state.value)}>Submit</button>
        </div>
    );
}

S
Shivprasad P

React components must wrapperd in single container,that may be any tag e.g. "< div>.. < / div>"

You can check render method of ReactCSSTransitionGroup


O
Ocko

Import view and wrap in View. Wrapping in a div did not work for me.

import { View } from 'react-native';
...
    render() {
      return (
        <View>
          <h1>foo</h1>
          <h2>bar</h2>
        </View>
      );
    }

thats because you are using react native.
And fragments are also available in React Native, so a View is not really the best solution.
K
KARTHIKEYAN.A

Invalid: Not only child elements

render(){
        return(
            <h2>Responsive Form</h2>
            <div>Adjacent JSX elements must be wrapped in an enclosing tag</div>
            <div className="col-sm-4 offset-sm-4">
                <form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
                    <div className="form-group">
                        <label for="name">Name</label>
                        <input type="text" className="form-control" id="name" />
                    </div>
                    <div className="form-group">
                        <label for="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="email" aria-describedby="emailHelp" />
                    </div>
                    <div className="form-group">
                        <label for="message">Message</label>
                        <textarea className="form-control" rows="5" id="message"></textarea>
                    </div>
                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
            </div>
        )
    }

Valid: Root element under child elements

render(){
        return(
          <div>
            <h2>Responsive Form</h2>
            <div>Adjacent JSX elements must be wrapped in an enclosing tag</div>
            <div className="col-sm-4 offset-sm-4">
                <form id="contact-form" onSubmit={this.handleSubmit.bind(this)} method="POST">
                    <div className="form-group">
                        <label for="name">Name</label>
                        <input type="text" className="form-control" id="name" />
                    </div>
                    <div className="form-group">
                        <label for="exampleInputEmail1">Email address</label>
                        <input type="email" className="form-control" id="email" aria-describedby="emailHelp" />
                    </div>
                    <div className="form-group">
                        <label for="message">Message</label>
                        <textarea className="form-control" rows="5" id="message"></textarea>
                    </div>
                    <button type="submit" className="btn btn-primary">Submit</button>
                </form>
            </div>
          </div>
        )
    }

Please avoid "me too" type answers or repeating the same solution, unless you have something relevant to add to it.
M
MiniGod

Just add

<>
  // code ....
</>

G
Gurjinder Singh

For Rect-Native developers. I encounter this error while renderingItem in FlatList. I had two Text components. I was using them like below

renderItem = { ({item}) => 
     <Text style = {styles.item}>{item.key}</Text>
     <Text style = {styles.item}>{item.user}</Text>
}

But after I put these tow Inside View Components it worked for me.

renderItem = { ({item}) => 
   <View style={styles.flatview}>
      <Text style = {styles.item}>{item.key}</Text>
      <Text style = {styles.item}>{item.user}</Text>
   </View>
 }

You might be using other components but putting them into View may be worked for you.


Fragments are also available in React Native, so a View is not really the best solution.
S
Sangha11

I think the complication may also occur when trying to nest multiple Divs within the return statement. You may wish to do this to ensure your components render as block elements.

Here's an example of correctly rendering a couple of components, using multiple divs.

return (
  <div>
    <h1>Data Information</H1>
    <div>
      <Button type="primary">Create Data</Button>
    </div>
  </div>
)

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now