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

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

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)部分(我希望这些div元素在提交的变量被设置为false时显示出来)。

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

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

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


当前回答

这个问题

解析错误:相邻的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>
  );
}

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

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

解决方案

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

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 ( <> <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中有一个规则,即JSX表达式必须只有一个最外层元素。

错误的

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

正确的

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

很简单,我们可以使用父元素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包装 元素,我们可以用hoc来包装。

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

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

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

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

e.g

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(只是为了说明,实际上你会得到错误:相邻的JSX元素必须被封装在一个封闭的标记中)

_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。

反应。Fragments (<React.Fragments>)稍微快一点,占用内存更少(不需要创建额外的DOM节点,DOM树不那么杂乱)。

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

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

而不是:

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

你可以这样写:

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

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

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

可以写成:

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

警告:数组或迭代器中的每个子元素都应该有一个唯一的“key”道具。检查“YourComponent”的渲染方法。

这可以通过为组件添加一个key属性来修复,如果手动添加这些属性,则如下所示:

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

这里有更多关于键的信息:组合与继承