Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 什么';确定关键属性的正确方法是什么?_Reactjs_React Native - Fatal编程技术网

Reactjs 什么';确定关键属性的正确方法是什么?

Reactjs 什么';确定关键属性的正确方法是什么?,reactjs,react-native,Reactjs,React Native,我正在努力学习英语。我正在看(谢谢Joshua!)在这个示例中,Joshua使用React以可控的方式小心地将图像元素放置在移动显示屏上。注意:他只使用了三个图像,并在文档中重复了几次。不幸的是,如前所述,该示例生成了一个警告: 警告:数组或迭代器中的每个子级都应具有唯一的“键” 道具检查YourProjectNameHere的渲染方法。看见 了解更多信息。(链接从缩写形式推断…) 我完全理解一行中的每一个元素以及React生成的每一行,我不清楚的是如何做到这一点。这是我的工作方法key={Ma

我正在努力学习英语。我正在看(谢谢Joshua!)在这个示例中,Joshua使用React以可控的方式小心地将图像元素放置在移动显示屏上。注意:他只使用了三个图像,并在文档中重复了几次。不幸的是,如前所述,该示例生成了一个警告:

警告:数组或迭代器中的每个子级都应具有唯一的“键” 道具检查
YourProjectNameHere
的渲染方法。看见 了解更多信息。(链接从缩写形式推断…)

我完全理解一行中的每一个元素以及React生成的每一行,我不清楚的是如何做到这一点。这是我的工作方法
key={Math.random()}

这个黑客很好用,但是看起来。。。错。这里的问题是,识别单个图像ID和单个行ID的正确方法是什么

'use strict';

 var React = require('react-native');
 var {
   AppRegistry,
   StyleSheet,
   Text,
   View,
   Image,
   Dimensions,
   ScrollView
 } = React;

 var _ = require('lodash');
 var {width, height} = Dimensions.get('window');

 var IMAGE_URLS = _.flatten(_.times(9, () => {return ['http://rnplay.org/IMG_0599.jpg', 'http://rnplay.org/IMG_0602.jpg', 'http://rnplay.org/IMG_0620.jpg']}));  // 9 x 3 = 27 images
 var IMAGES_PER_ROW = 4;

 var AwesomeProject1 = React.createClass({

   getInitialState() {
     return {
       currentScreenWidth: width,
       currentScreenHeight: height
     }
   },

   handleRotation(event) {
     var layout = event.nativeEvent.layout
     this.setState({currentScreenWidth: layout.width, currentScreenHeight: layout.height })
   },

   calculatedSize() {
     var size = this.state.currentScreenWidth / IMAGES_PER_ROW
     return {width: size, height: size}
   },


   // note:  I added key={Math.random()} in two places below.
   // Its a BS fix, but it seems to work to avoid the warning message.
   renderRow(images) {
     return images.map((uri) => {
       return (
         <Image style={[styles.image, this.calculatedSize()]} key={Math.random()} source={{uri: uri}} />  //key={Math.random()}
       )
     })
   },

   renderImagesInGroupsOf(count) {
     return _.chunk(IMAGE_URLS, IMAGES_PER_ROW).map((imagesForRow) => {
       return (
         <View style={styles.row} key={Math.random()}>
           {this.renderRow(imagesForRow)}
         </View>
       )
     })
   },

   render: function() {
     return (
       <ScrollView onLayout={this.handleRotation} contentContainerStyle={styles.scrollView}>
         {this.renderImagesInGroupsOf(IMAGES_PER_ROW)}
       </ScrollView>
     );
   }
 });

 var styles = StyleSheet.create({

   row: {
     flexDirection: 'row',
     alignItems: 'center',
     justifyContent: 'flex-start'
   },

   image: {
   }
 });

 AppRegistry.registerComponent('AwesomeProject1', () => AwesomeProject1);

我认为,只有当您要移动组件(例如,更改顺序)或预先添加元素时,关键点才真正相关。如果这不是您的问题,并且您只想使警告静音,那么可以使用数组索引(第二个参数到
map()

React对账算法的简短官方解释在中

扩展答案 我将对此展开讨论,因为我相信你们接受的另一个答案是误导性的:它本身并不是一个合法的解决方案

我的理解是React将作为数组的元素子元素解释为一种特殊情况,在这种情况下,元素的长度或相对位置可能会改变,而组件实例需要保留。在本书中,他们这样描述:

当子项被随机移动(如在搜索结果中)或如果新组件被添加到列表的前面(如在流中)

但通常使用数组只是为了方便编写脚本生成子对象,否则子对象可以按字面/静态方式表示。我想你就是这样。如果不是这样,您将需要并且可能已经拥有合法的唯一ID。例如,如果我正确理解您的用例,您可以这样做,在这种情况下,React不会发出关键警告:

var image\u url=[
'http://rnplay.org/IMG_0599.jpg',
'http://rnplay.org/IMG_0602.jpg',
'http://rnplay.org/IMG_0620.jpg'
];
{/* #1 */}
{/* ... */
{/*#n*/}
显然,这是一种可怕的方法,因此使用了数组。但是React并没有将数组的使用(编写等价的脚本)与另一种情况(元素的长度和顺序是动态的)区分开来您可以忽略警告,但只需指定元素的索引值就可以轻松地消除警告

。这些变体产生等效的输出,但不同之处在于它们是否被逐字声明或编写脚本并发出关键警告

var container=document.getElementById('container');
风险值项目=[“A”、“B”、“C”];
变量组=数组(2)。填充(项目);
函数渲染(元素){
ReactDOM.render(
元素,
容器
);
}
log(“文字,无按键警告”);
变量元素=
{items[0]}
{items[1]}
{项目[2]}
{items[0]}
{items[1]}
{项目[2]}
;
渲染(元素);
log(“脚本化,无键警告”);
变量元素=
{groups.map((items,i)=>
{items.map((item,j)=>
{item}
)}
)}
;
渲染(元素);
log(“脚本化,带有关键警告”);
变量元素=
{groups.map((items,i)=>
{items.map(item=>
{item}
)}
)}
;
渲染(元素);
钥匙是react的渲染方式,用于确定分配给该节点的对象是否已更改。这是一种优化策略。如果为该渲染的特定节点分配的键与上次渲染时分配的键相同,则无需重新渲染。因此,您希望每个键对该节点都是唯一的,但同时也是可预测/一致的e可猜测,因此每次渲染该特定节点时,都会为其指定完全相同的唯一键

Math.random()对于键来说是一个糟糕的选择,因为它不符合可预测/一致的条件。出于类似的原因,单独使用数组索引也是一个糟糕的选择

相反,我建议使用数组值+索引

renderRow(images) {
     return images.map((uri, idx, arr) => {
       return (
         <Image style={[styles.image, this.calculatedSize()]} key={uri.concat(idx)} source={{uri: uri}} />  
       )
     })
   },
renderRow(图像){
返回images.map((uri、idx、arr)=>{
返回(
)
})
},

return images.map((uri,idx,arr)=>{…所以我就把它漏掉了。这是一种尝试,还是一个特定的教学点?似乎效果很好,是的,我知道随机的东西很糟糕,很糟糕。我会更新我的问题,根据这个答案显示正确的代码。Thx!他只是在使用
map
的完整方法签名。没错,正如@interrobang指出,我只是在使用完整签名。如果您选择,您可以安全地忽略它。这并不是唯一标识组件实例,它仍然使用索引。这只在仅使用索引的情况下可靠地工作。如果您确实需要唯一标识每个组件(例如,因为它是有状态的,并且它们可以重新排序)无论如何,您都需要一个唯一的ID。而且它没有说明如何处理
组件。这是我的观点,这不是一个健壮的解决方案&实际上可能并不比只使用索引好。如果需要,它不允许交换表示
a
的两个组件(例如,如果它们是有状态的)。而交换
A
B
不应该破坏实例——这与
key
的目的大相径庭。如果您确实需要唯一地标识实例,例如编号
renderRow(images) {
     return images.map((uri, idx, arr) => {
       return (
         <Image style={[styles.image, this.calculatedSize()]} key={uri.concat(idx)} source={{uri: uri}} />  
       )
     })
   },