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

我试图设置我的React.js应用程序,以便它只呈现如果我设置的变量是true

我的渲染函数是这样设置的:

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

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

但是当运行这个时,我在问题中得到了错误:

解析错误:第38行:相邻的JSX元素必须被封装在一个外围标记中

这里的问题是什么?我该怎么做呢?

558448 次浏览

React元素只能返回一个元素。您必须用另一个元素标记来包装两个标记。

我还可以看到你的渲染函数没有返回任何东西。这是你的组件应该看起来的样子:

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

还要注意,你不能在返回的元素中使用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 />
}
},

你应该把你的组件放在一个封闭标签之间,这意味着:

// WRONG!


return (
<Comp1 />
<Comp2 />
)

而不是:

// Correct


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

根据Joe Clay对碎片API的评论

// More Correct


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


// Short syntax


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

现在回答这个问题已经晚了,但我认为它会增加解释。

这是因为在代码的任何地方都同时返回两个元素。

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

它应该被包装在元素中。如

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

更详细说明

转换下面的jsx代码

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

到这个

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

但如果你这样做

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

this被转换成this(只是为了说明,实际上你会得到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'
)
}
}]);

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

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

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

React.Fragments (<React.Fragments>)稍微快一点,内存占用更少(不需要创建额外的DOM节点,更整洁的DOM树)。

如# EYZ0

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

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

render() {
return [
"Some text.",
<h2 key="heading-1">A heading</h2>,
"More text.",
<h2 key="heading-2">Another heading</h2>,
"Even more text."
];
}

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

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

可以写成:

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

请注意,上面将生成一个警告:Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of 'YourComponent'.

这可以通过添加key属性来修复,如果手动添加这些属性,可以这样添加:

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

下面是关于键的更多信息:组合vs继承

这个问题

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

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

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

将转化为:

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

除非您是编程新手,否则您已经知道(任何语言的)函数/方法可以接受任意数量的参数,但总是只返回一个值。鉴于此,您可能会发现,当尝试根据createElement()的工作方式返回多个兄弟组件时,就会出现问题;它只接受一个元素的参数并返回。因此,一次函数调用不能返回多个元素。


所以如果你想知道为什么这样做…

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

但不是这个……

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

这是因为在第一个代码片段中,# eyz0 -元素都是# eyz2 -元素的children的一部分。当它们是children的一部分时,我们可以表达无限数量的兄弟元素。看看这句话是怎么说的:

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

解决方案

取决于你正在运行的React版本,你确实有几个选项来解决这个问题:

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

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

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

    • 数组中的子数组必须用逗号分隔。
    • 数组中的子数组必须有一个键来防止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>
    );
    }
    

    # EYZ0。< / p >

导入视图并在View中进行包装。把div包装起来对我没用。

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

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

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

React 16.2.0 >我们可以在一个Fragment标签中返回多个渲染组件。# EYZ1

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

React 16.2.0 >您可以使用这种速记语法。(一些较旧的工具版本不支持它,因此您可能希望显式地编写<Fragment>,直到工具赶上。)

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

React 16将你的返回值作为一个数组,所以它应该被一个元素包装,比如div。

错误的方法

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


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


);
}

正确方法(一个div或其他元素中的所有元素)

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


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

# EYZ0 # EYZ1

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

# EYZ0 # EYZ1

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

React组件必须包装在单个容器中,可以是任何标签 如。“& lt;div > . .& lt;/ div > " < / >强

你可以检查ReactCSSTransitionGroup的渲染方法

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

错误的

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

正确的

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

如果你不包装你的组件,那么你可以按照下面提到的方法来编写它。

而不是:

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

你可以这样写:

return[(
<Comp1 />
),
(
<Comp2 />
) ];
很简单,我们可以使用父元素div来包装所有元素 或者我们可以使用高阶分量(HOC)的概念,即非常有用的 React js应用程序

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

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

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

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

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


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

对于Rect-Native开发者。我在FlatList中renderingItem时遇到了这个错误。我有两个文本组件。我是这样使用它们的

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

但是在我把这两个内部视图组件后,它为我工作。

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

您可能正在使用其他组件,但将它们放入View可能对您有用。

我认为当试图在return语句中嵌套多个div时,也会出现复杂情况。您可能希望这样做,以确保您的组件呈现为块元素。

下面是一个使用多个div正确呈现两个组件的例子。

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

只需添加

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