如何在 React 的另一个返回语句中返回多行 JSX?

IT技术 javascript reactjs
2021-01-21 10:16:01

一行工作正常:

render: function () {
  return (
    {[1,2,3].map(function (n) {
      return <p>{n}</p>
    }}
  );
}

但不适用于多行:

render: function () {
  return (
    {[1,2,3].map(function (n) {
      return (
        <h3>Item {n}</h3>
        <p>Description {n}</p>
      )
    }}
  );
}
6个回答

尝试将标记视为函数调用(请参阅文档)。然后第一个变成:

{[1,2,3].map(function (n) {
  return React.DOM.p(...);
})}

第二个:

{[1,2,3].map(function (n) {
  return (
    React.DOM.h3(...)
    React.DOM.p(...)
  )
})}

现在应该很清楚第二个代码段没有意义(在 JavaScript 中不能返回多个值)。您必须将它包装在另一个元素中(很可能是您想要的,这样您还可以提供有效的key属性),或者您可以使用以下内容:

{[1,2,3].map(function (n) {
  return ([
    React.DOM.h3(...),
    React.DOM.p(...)
  ]);
})}

使用JSX语法糖:

{[1,2,3].map(function (n) {
  return ([
    <h3></h3>, // note the comma
    <p></p>
  ]);
})}

您不需要展平结果数组。React 会为你做到这一点。请参阅以下小提琴http://jsfiddle.net/mEB2V/1/再说一遍:将两个元素包装到一个 div/section 中很可能从长远来看会更好。

这不再有效(从 0.9ish 开始) Uncaught Error: Invariant Violation: Product.render(): A valid ReactComponent must be returned. You may have returned undefined, an array or some other invalid object.
2021-03-13 10:16:01
@TimFletcher 可以渲染组件的过程中返回一个数组,例如<div>{ this.props.foos.map(function() { return <Foo /> }) }</div>. 但是render组件函数不能在没有包装它的情况下返回该数组,例如在一个 div 中。
2021-03-24 10:16:01
谢谢!直到!更新我的答案以包含指向 JSFiddle 的链接,该链接显示 flatten 是可选的。还将包含 React 文档的链接。
2021-03-28 10:16:01
是的,实际上清楚地记录了facebook.github.io/react/tips/...
2021-04-07 10:16:01
使用没有 flatten 位的 return ([...]) 给了我完全符合我的要求的标记,虽然返回的数组必须没有被扁平化,但在我的特殊情况下它不会影响最终输出。或者是吗?
2021-04-09 10:16:01

似乎Jan Olaf Krems关于返回数组的答案不再适用(也许因为 React ~0.9,正如@dogmatic69 在评论中所写)。

文档说你需要返回一个节点:

JSX 根节点的最大数量

目前,在一个组件的渲染中,你只能返回一个节点;例如,如果您有一个要返回的 div 列表,则必须将组件包装在 div、span 或任何其他组件中。

别忘了 JSX 会编译成普通的 JS;返回两个函数并没有真正的语法意义。同样,不要将一个以上的孩子放在三元组中。

在许多情况下,您可以简单地将内容包装在 a<div>或 a 中<span>

就我而言,我想返回多个<tr>s。我将它们包裹在一个<tbody>- 一张桌子上可以有多个物体。

从 React 16.0 开始,显然再次允许返回数组,只要每个元素都有一个key新的渲染返回类型:片段和字符串

React 16.2 允许您使用<Fragment>…</Fragment>或 甚至包围元素列表<>…</>,如果您更喜欢数组:https : //reactjs.org/docs/fragments.html

如果你想返回多个,你能做什么<li>假设我不能把它全部包起来<ul>
2021-03-15 10:16:01
@Banjocat ......我很想知道你的问题的更好答案。也许你应该把它作为一个常规的 stackoverflow 问题,看看你是否得到了不同的答案。
2021-03-16 10:16:01
@Banjocat 恐怕我不知道:/ 您可以嵌套列表,因此您可以返回类似<li><ul><li>one</li><li>two</li></ul></li>在您的情况下有效的内容。或者:包装 div 不是严格有效的,但它可能在所有相关浏览器中都能正常呈现?如果您尝试一下,请告诉我们。
2021-03-22 10:16:01
@HenrikN Fwiw,将 a 的“子集”包装lispanordiv中对我来说效果不佳。div 严重破坏了渲染,至少在我的用例中,跨度搞砸了 CSS。2¢:试图返回lis 的几个子集是一种代码味道。我们使用 aul作为一种下拉菜单,我最初希望许多组件返回lis 的“部分” 最后,最好将所有菜单代码放在一个“锚定”于 at 的组件中,而ul不是li从多个来源塞入s。我认为它也使 UI 的心智模型更加清晰。
2021-04-03 10:16:01
@user1175849 也许可以发布这个问题:)
2021-04-09 10:16:01

React v16.0.0开始,可以通过多个元素包装在一个 中返回多个元素Array

render() {
  return (
    {[1,2,3].map(function (n) {
      return [
        <h3>Item {n}</h3>.
        <p>Description {n}</p>
      ]
    }}
  );
}

同样从React v16.2.0 开始React Fragments引入了一个名为的新功能,您可以使用它来包装多个元素:

render() {
  return (
    {[1,2,3].map(function (n, index) {
      return (
        <React.Fragment key={index}>
            <h3>Item {n}</h3>
            <p>Description {n}</p>
        </React.Fragment>
      )
    }}
  );
}

根据文档:

React 中的一个常见模式是组件返回多个元素。Fragments 允许您对子项列表进行分组,而无需向 DOM 添加额外的节点。

使用显式 <React.Fragment> 语法声明的片段可能有键。一个用例是将一个集合映射到一个片段数组——例如,创建一个描述列表:

function Glossary(props) {
  return (
    <dl>
      {props.items.map(item => (
        // Without the `key`, React will fire a key warning
        <React.Fragment key={item.id}>
          <dt>{item.term}</dt>
          <dd>{item.description}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}

key 是唯一可以传递给 Fragment 的属性。将来,我们可能会添加对其他属性的支持,例如事件处理程序。

此外,您可能希望在 React 组件内的某个辅助函数中返回多个列表项。只需返回具有以下key属性的 HTML 节点数组

import React, { Component } from 'react'

class YourComponent extends Component {
  // ...

  render() {
    return (
      <ul>
        {this.renderListItems()}
      </ul>
    )
  }

  renderListItems() {
    return [
      <li key={1}><a href="#">Link1</a></li>,
      <li key={2}><a href="#">Link2</a></li>,
      <li key={3} className="active">Active item</li>,
    ]
  }
}

更新

使用react片段。这很简单。链接到片段文档。

render() {
  return (
    <>
    {[1,2,3].map((value) => <div>{value}</div>)}
    </>
  );
}

旧答案 - 已过时

随着 React > 16 你可以使用react-composite

import { Composite } from 'react-composite';

// ...

{[1,2,3].map((n) => (
  <Composite>
    <h2>Title {n}</h2>
    <p>Description {n}</p>
  </Composite>
))};

当然,必须安装react-composite。

npm install react-composite --save