Javascript 解析错误:必须将相邻的 JSX 元素包装在封闭标记中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31284169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:29:28  来源:igfitidea点击:

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

javascriptreactjsrender

提问by user1072337

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

我正在尝试设置我的React.js应用程序,以便它仅在我设置的变量为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 divelements to show up when the submitted variable is set to false).

基本上,这里重要的部分是if(this.state.submitted==false)部分(我希望这些div元素在提交的变量设置为 时显示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

未捕获的错误:解析错误:第 38 行:必须将相邻的 JSX 元素包装在封闭标记中

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

这里有什么问题?我可以用什么来完成这项工作?

回答by wdanxna

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

编辑:Per Joe Clay 对Fragments API的评论

// More Correct

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

// Short syntax

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

回答by WitVault

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 parentelement. e.g

它应该被包裹在一个元素中。例如

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



More Detailed Explanation更详细的解释

Your below jsxcode get transformed

您的以下jsx代码已转换

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)

这被转换成这个(只是为了说明目的,实际上你会得到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 twicefrom a method call, which is obviously wrong.

在上面的代码中你可以看到你试图从一个方法调用中返回两次,这显然是错误的。

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

编辑 - React 16 和自己的病房的最新变化:

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.

如果您不想添加额外的 div 来环绕并且想要返回多个子组件,您可以使用React.Fragments.

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

React.Fragments速度更快,内存使用更少(无需创建额外的 DOM 节点,减少混乱的 DOM 树)。

e.g (In React 16.2.0)

例如(在 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."
 ];
}

回答by Matan Gubkin

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

React 元素必须只返回一个元素。你必须用另一个元素标签包装你的两个标签。

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 ifstatements inside of a returned element:

另请注意,您不能if在返回的元素内使用语句:

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

回答by Neal

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.

如果您不想像其他答案所建议的那样将它包装在另一个 div 中,您也可以将它包装在一个数组中,它会起作用。

// 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'.

请注意,以上内容会产生警告: 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 keyattribute to the components, if manually adding these add it like:

这可以通过向key组件添加属性来解决,如果手动添加这些属性,则将其添加为:

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

Here is some more information on keys:Composition vs Inheritance

以下是有关键的更多信息:组合与继承

回答by Chris

The problem

问题

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

解析错误:必须将相邻的 JSX 元素包装在封闭标记中

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:

这意味着您试图以不正确的方式返回多个同级 JSX 元素。请记住,您不是在编写 HTML,而是在编写 JSX!您的代码从 JSX 转换为 JavaScript。例如:

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 onevalue. 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 oneelement and returns that. Hence we cannot return multiple elements from one function call.

除非您一般不熟悉编程,否则您已经知道(任何语言的)函数/方法接受任意数量的参数但始终只返回一个值。鉴于此,您可能会发现当尝试根据工作方式返回多个同级组件时会出现问题createElement();它只接受一个元素的参数并返回它。因此,我们不能从一个函数调用中返回多个元素。



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 childrenof the <div>-element. When they are part of childrenthen we can express an unlimited number of sibling elements. Take a look how this would transpile:

这是因为在第一个片段,无论是<p>-elements是部分children的中<div>-元素。当它们成为一部分时,children我们可以表达无限数量的兄弟元素。看看这将如何转换:

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:

根据您运行的 React 版本,您有几个选项可以解决这个问题:

  • Use fragments (React v16.2+ only!)

    As of React v16.2, React has support for Fragmentswhich 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 (
        <>
          <ChildA />
          <ChildB />
          <ChildC />
        </>
      );
    }
    

    which de-sugars into:

    render() {
      return (
        <React.Fragment>
          <ChildA />
          <ChildB />
          <ChildC />
        </React.Fragment>
      );
    }
    

    Note that the first snippet requires Babel v7.0 or above.


  • 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 [<p key={0}>foo</p>, <p key={1}>bar</p>];
    }
    

    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 (<p>foo</p> <p>bar</p>);
    }
    

  • 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 (
        <div>
          <h1>foo</h1>
          <h2>bar</h2>
        </div>
      );
    }
    

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

  • 使用片段(仅限 React v16.2+!)

    从 React v16.2 开始,React 支持Fragments,这是一个直接返回其子项的无节点组件。

    返回数组中的孩子(见下文)有一些缺点:

    • 数组中的子项必须用逗号分隔。
    • 数组中的子项必须有一个键来防止 React 的键警告。
    • 字符串必须用引号括起来。

    这些从片段的使用中被消除。这是一个包裹在片段中的孩子的例子:

    render() {
      return (
        <>
          <ChildA />
          <ChildB />
          <ChildC />
        </>
      );
    }
    

    其中脱糖为:

    render() {
      return (
        <React.Fragment>
          <ChildA />
          <ChildB />
          <ChildC />
        </React.Fragment>
      );
    }
    

    请注意,第一个代码段需要 Babel v7.0 或更高版本。


  • 返回一个数组(仅限 React v16.0+!)

    从 React v16 开始,React Components 可以返回数组。这与早期版本的 React 不同,在早期版本中,您被迫将所有兄弟组件包装在父组件中。

    换句话说,您现在可以执行以下操作:

    render() {
      return [<p key={0}>foo</p>, <p key={1}>bar</p>];
    }
    

    这转化为:

    return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")];
    

    请注意,以上返回一个数组。自 React 16 及更高版本以来,数组是有效的 React 元素。对于早期版本的 React,数组不是有效的返回对象!

    另请注意,以下内容无效(您必须返回一个数组):

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

  • 将元素包裹在父元素中

    另一种解决方案涉及创建一个父组件,该组件将兄弟组件包装在其children. 这是迄今为止解决此问题的最常见方法,并且适用于所有版本的 React。

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

    注意:再次查看此答案的顶部以了解更多详细信息以及它如何转换.

回答by Morris S

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

React 16.0.0我们可以从渲染返回多个组件作为数组。

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

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

React 16.4.0我们可以在 Fragment 标签中从渲染返回多个组件。分段

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

Future Reactyou wil be able to use this shorthand syntax. (many tools don't support it yet so you might want to explicitly write <Fragment>until the tooling catches up.)

未来的 React你将能够使用这种速记语法。(许多工具尚不支持它,因此您可能希望<Fragment>在工具赶上之前明确编写。)

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

回答by 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 />
) ];

回答by Fazal

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

非常简单,我们可以使用父元素 div 来包装所有元素,或者我们可以使用高阶组件(HOC's)概念,即对于 react js 应用程序非常有用

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

或者另一种最好的方法是 HOC,它非常简单而不是非常复杂,只需在您的项目中添加一个文件 hoc.js 并简单地添加这些代码

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.

现在在你想使用的地方导入 hoc.js 文件,现在我们可以用 hoc 包装而不是用 div 元素包装。

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

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

回答by Khandelwal-manik

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

react 有一条规则,即 JSX 表达式必须恰好有一个最外层元素。

wrong

错误的

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

correct

正确的

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

回答by Shivprasad P

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

React 组件必须包装在单个容器中,可以是任何标签, 例如“<div>..</div>”

You can check render method of ReactCSSTransitionGroup

您可以检查 ReactCSSTransitionGroup 的渲染方法