如何在 React 的另一个 return 语句中返回多行 JSX?
Posted
技术标签:
【中文标题】如何在 React 的另一个 return 语句中返回多行 JSX?【英文标题】:How can I return multiple lines JSX in another return statement in React? 【发布时间】:2014-07-13 12:11:33 【问题描述】:单行可以正常工作:
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>
)
);
【问题讨论】:
有关此特定问题的更多信息:github.com/facebook/react/issues/2127 不是return ("asdf" "asdf");
你想要return ["asdf", "asdf"];
【参考方案1】:
尝试将标签视为函数调用(参见the documentation)。那么第一个就变成了:
[1,2,3].map(function (n)
return React.DOM.p(...);
)
第二个:
[1,2,3].map(function (n)
return (
React.DOM.h3(...)
React.DOM.p(...)
)
)
现在应该清楚第二个 sn-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 很可能会更好。
【讨论】:
是的,实际上已经清楚地记录了facebook.github.io/react/tips/… 使用没有 flatten 位的 return ([...]) 可以让我得到完全符合我要求的标记,尽管返回的数组不能被展平,但在我的特定情况下它不会影响最终输出。还是这样? 谢谢!直到!更新我的答案以包含指向显示 flatten 是可选的 JSFiddle 的链接。还将包含 React 文档的链接。 这不再有效(截至 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.
@TimFletcher 可以返回一个数组作为渲染组件的一部分,例如<div> this.props.foos.map(function() return <Foo /> ) </div>
。但是组件的 render
函数不能在不包装的情况下返回该数组,例如在一个 div 中。【参考方案2】:
似乎 Jan Olaf Krems's answer 关于返回一个数组不再适用(可能从 React ~0.9 开始,正如 @dogmatic69 在 a comment 中所写)。
The documentation 表示需要返回单个节点:
JSX 根节点的最大数量
目前,在组件的渲染中, 您只能返回一个节点;如果你有一个 div 列表 返回,您必须将组件包装在 div、span 或任何其他 组件。
别忘了 JSX 会编译成普通的 JS;返回两个 函数并没有真正的语法意义。同样,不要放 三元组中不止一个孩子。
在许多情况下,您可以简单地将内容包装在 <div>
或 <span>
中。
就我而言,我想返回多个<tr>
s。我将它们包裹在 <tbody>
中——一个表格可以有多个主体。
从 React 16.0 开始,显然再次允许返回一个数组,只要每个元素都有一个 key
:New render return types: fragments and strings
React 16.2 允许您使用 <Fragment>…</Fragment>
甚至 <>…</>
包围元素列表,如果您更喜欢使用数组:https://reactjs.org/docs/fragments.html
【讨论】:
如果要返回多个<li>
怎么办?假设我不能把它全部包装在<ul>
@Banjocat 恐怕我不知道:/ 你可以嵌套列表,所以你可以返回类似<li><ul><li>one</li><li>two</li></ul></li>
的东西,如果这适用于你的情况.或者:包装 div 不会严格有效,但也许它在所有相关浏览器中都可以正常呈现?如果您尝试过,请告诉我们。
@Banjocat...我很想知道您的问题的更好答案。也许你应该把它当作一个常规的 *** 问题,看看你是否得到不同的答案。
@user1175849 也许你可以发布那个问题:)
@HenrikN Fwiw,将li
的“子集”包装在span
或div
对我来说效果不佳。 div 严重破坏了渲染,而且,至少在我的用例中,span 弄乱了 CSS。 2¢: 尝试返回 li
s 的几个子集是代码异味。我们使用ul
作为一种下拉菜单,我最初希望许多组件返回li
s 的“部分”。最后,最好将所有菜单代码放入“锚定”在ul
的单个组件中,而不是从多个来源中硬塞到li
s 中。我认为它还让 UI 的心智模型更加简洁。【参考方案3】:
从 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 中的一个常见模式是组件返回多个 元素。片段可让您对子列表进行分组而无需添加 DOM 的额外节点。
使用显式
语法声明的片段可能有 键。一个用例是将一个集合映射到一个数组 片段——例如,创建一个描述列表: 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 的属性。在里面 将来,我们可能会添加对其他属性的支持,例如事件 处理程序。
【讨论】:
【参考方案4】:此外,您可能希望在 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>,
]
【讨论】:
【参考方案5】:更新
使用反应片段。这很简单。 Link 分片文档。
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
【讨论】:
【参考方案6】:您可以在此处使用createFragment
。请参阅Keyed Fragments。
import createFragment from 'react-addons-create-fragment';
...
[1,2,3].map((n) => createFragment(
h: <h3>...</h3>,
p: <p>...</p>
)
)
(我在这里使用ES6 和JSX 语法。)
您首先必须添加react-addons-create-fragment
包:
npm install --save react-addons-create-fragment
Jan Olaf Krems's solution 的优势:React 不会抱怨缺少 key
。
【讨论】:
如果我错了,请纠正我,但您可以手动添加密钥。使用 jan 的示例:第一个数组项获取例如 和第二个数组项略有不同,例如key=i + '-foo'>
【参考方案7】:通过 React 片段 <></>
和 React.Fragment
很简单:
return (
<>
[1, 2, 3].map(
(n, index): ReactElement => (
<React.Fragment key=index>
<h3>Item n</h3>
<p>Description n</p>
</React.Fragment>
),
)
</>
);
【讨论】:
【参考方案8】:当您不在当前项目中时会发生这种情况,我在一个文件夹中有三个项目并出现此错误。
一旦切换到项目,问题就消失了。
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于如何在 React 的另一个 return 语句中返回多行 JSX?的主要内容,如果未能解决你的问题,请参考以下文章
在 React 渲染方法中使用 for 在 return 语句中失败