【问题标题】:Why can't you have multiple parent elements in a component?为什么一个组件中不能有多个父元素?
【发布时间】:2021-06-16 04:00:22
【问题描述】:

我是新手,如果我在return() 中编写此代码,我会收到此错误:

JSX 表达式必须有一个父元素。

class Header extends React.Component {
  render() {
    return (
      
        <Navbar bg="dark" variant="dark" className="fixed-top-nav">
          <Navbar.Brand href="#home">Crypto Currency</Navbar.Brand>
        </Navbar>

        <Jumbotron fluid className="mb-0"></Jumbotron>

    );
  }
}

我明白,如果我用&lt;div&gt; 围绕下面的代码,就像下面的代码一样,它工作得很好。

class Header extends React.Component {
  render() {
    return (
      <div>
        <Navbar bg="dark" variant="dark" className="fixed-top-nav">
          <Navbar.Brand href="#home">Crypto Currency</Navbar.Brand>
        </Navbar>

        <Jumbotron fluid className="mb-0"></Jumbotron>
      </div>
    );
  }
}

我想知道为什么你不能在一个组件中拥有多个间接父母?

【问题讨论】:

  • 因为他们希望你有一个父母。如果你不想要这个 div,你可以用一个片段来包装它。您需要意识到 JSX 在幕后被编译为“创建元素行”,因此它需要一个元素。

标签: javascript html reactjs jsx


【解决方案1】:

这是因为 JSX 是如何编译成 Javascript 的:

const myJSXValue = &lt;span&gt;Some text&lt;/span&gt;

变成

const myJSXValue = React.createElement("span", null, "Some text");

换句话说,它正在为元素创建一个函数调用,然后可以将其作为良好的 ol' JavaScript 传递。

JSX 依赖于单个函数调用,即使该函数调用最终嵌套了更多,因此它可以被传递并从函数返回。 JavaScript 函数可以返回多少个值?只有一个 :) 即使该单个值再次包含其他值,例如数组。

一个包装好的例子:

const myJSXValue = &lt;&gt;&lt;span&gt;Some text&lt;/span&gt;&lt;span&gt;Some more text&lt;/span&gt;&lt;/&gt;

变成

const myJSXValue = React.createElement(React.Fragment, null, React.createElement("span", null, "Some text"), React.createElement("span", null, "Some more text"));

如您所见,由于它是由单个父项包装的,因此 myJSXValue 被分配了一个函数调用。 那个函数调用包括额外的调用,但在外层你有 1 个值。同样,当您有一个返回 JSX 值的组件时,您将返回 1 个单个值。

因此,您至少需要一个虚拟父元素来将您的子元素包装成一个可以传递(即从组件返回)的函数调用。

最简单的方法就是使用 React.Fragment,可以像上面的例子一样缩写为&lt;&gt;&lt;/&gt;

【讨论】:

  • 我不同意这一点。 JSX 可以检测到顶级相邻片段并自动将它们嵌套到像 React.Fragment 这样的瞬态容器中。他们选择不走那条路。不是因为不可能。
  • JavaScript 的基本原因仍然是一样的,不管他们是否为你修复它。
  • javascript 原因无关紧要。如果他们愿意,他们可以让它像 OP 想要的那样工作。
  • 这有点迂腐,但可以肯定。您也可以对大多数带有框架的东西这么说。为什么基于语言 L 的框架 F 做 T 事?因为 L 预计 T 和 F 没有对你隐瞒。
  • 说得好,现在我明白为什么你必须只有一个间接父母!
【解决方案2】:

你可以! React Fragment 就是为此而生的。

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

您可以在官方文档中了解更多信息: https://reactjs.org/docs/fragments.html

【讨论】:

  • 那么为什么你必须有一个片段作为父母?
  • 只有JSX 的语法细节。在 React Fragment 之前,这个细节导致了一个有意义的缺点(你不得不在 DOM 中乱扔无意义的divs)。但是现在你有了 Fragment,你可以忽略它作为语法选择。
【解决方案3】:

根据React Documentation for render method,预计会返回一个 React 元素(或 null)

React 构建和维护虚拟 DOM 以便运行。因此,预计只有一个元素将被视为该特定组件的 Root。

我们肯定会遇到这样的场景,我们可能需要返回多个元素。我们可以通过包装由React.Fragment<></> (v16.2+) 返回的元素组来做到这一点

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多