我在React Native中呈现ListView
,设法修复此React警告,但我不明白它是如何以及为什么有效:
警告:任何对键控对象的使用都应该在作为子进行传递之前包装在React.addons.createFragment(object)中。
// This array generates React Fragment warning.
var data1 = [{name: "bob"}, {name:"john"}]
// This array works, no warnings.
var data2 = [React.addons.createFragment({name: "bob"}),
React.addons.createFragment({name: "john"})]
// This also works, no warnings.
var data3 = ["bob", "john"]
class Listings extends React.Component {
constructor(props) {
super(props)
ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
this.state = {
dataSource: ds.cloneWithRows(data),
}
}
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => <Text>{rowData}</Text>} />
)
}
}
什么是反应片段? React什么时候需要?为什么键控对象会导致此警告?
答案 0 :(得分:15)
我将我的答案分为两部分,以涵盖我在你的问题中看到的两个要点。
为了解释 React Fragment 是什么,我们需要退一步讨论 React Keys 。
键帮助React识别哪些项已更改,已添加或已删除。它们应该被赋予数组中的元素,以赋予元素稳定的标识(唯一性)。
选择密钥的最佳方法是使用在其兄弟姐妹中唯一标识列表项的字符串。大多数情况下,您会使用数据中的ID作为键。这是一个实际的例子:
render() {
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
return todoItems;
}
重要的是要注意todoItems
实际上是一个<li>
元素数组。
知道这一点,让我们继续讨论您在用例中收到警告的原因。
在大多数情况下,您可以使用key
道具来指定从渲染中返回的元素上的键,就像上面的示例一样。但是,在一种情况下会出现这种情况:如果您有两组需要重新排序的子项,则无法在不添加包装元素的情况下在每个组上放置一个键。
以下是recently updated React docs:
中的经典示例function Swapper(props) {
let children;
if (props.swapped) {
children = [props.rightChildren, props.leftChildren];
} else {
children = [props.leftChildren, props.rightChildren];
}
return <div>{children}</div>;
}
当您更改swapped
道具时,孩子们将卸下并重新安装,因为两组孩子上没有标记任何钥匙。
要解决此问题,您可以使用createFragment加载项为子集提供密钥。 Follow the enhanced example, using the createFragment
here
无论如何,你得到错误的错误仅仅是因为你试图将一个JavaScript对象(而不是JSX元素或字符串)插入某个JSX中。
虽然错误消息建议使用createFragment
来解决这个问题,但原因是你将一个变量插入到一个不是字符串或JSX元素的JSX中,但实际上是其他类型的对象!
在您的用例中出现这种误导性警告,不是吗? : - )
答案 1 :(得分:0)
您可以通过以下方式从“反应”中导入片段:
import React, { Fragment } from "react";
然后将渲染功能更新为:
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={(rowData) => {
<Fragment key={passsKey}>
<Text>{rowData}</Text>
</Fragment>
}}
/>
)}