警告:列表中的每个孩子都应该有一个唯一的“key”属性。%s%s
Posted
技术标签:
【中文标题】警告:列表中的每个孩子都应该有一个唯一的“key”属性。%s%s【英文标题】:Warning: Each child in a list should have a unique "key" prop.%s%s 【发布时间】:2020-04-10 09:56:22 【问题描述】:大家好。
我正在做一个项目,我所在城市的餐馆可以通过应用程序放置菜肴并生成订单。
但我的项目在执行时出错。
这是我的错误。
Warning: Each child in a list should have a unique "key" prop.%s%s
Check the render method of `VirtualizedList`., ,
in CellRenderer (at VirtualizedList.js:767)
in VirtualizedList (at FlatList.js:676)
in FlatList (at Meals.tsx:14)
in RCTView (at Meals.tsx:12)
in Meals (at SceneView.js:9)
in SceneView (at StackViewLayout.tsx:900)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at StackViewCard.tsx:106)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at screens.native.js:100)
in Screen (at StackViewCard.tsx:93)
in Card (at createPointerEventsContainer.tsx:95)
in Container (at StackViewLayout.tsx:975)
in RCTView (at screens.native.js:131)
in ScreenContainer (at StackViewLayout.tsx:384)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at StackViewLayout.tsx:374)
in PanGestureHandler (at StackViewLayout.tsx:367)
in StackViewLayout (at withOrientation.js:30)
in withOrientation (at StackView.tsx:104)
in RCTView (at Transitioner.tsx:267)
in Transitioner (at StackView.tsx:41)
in StackView (at createNavigator.js:80)
in Navigator (at createKeyboardAwareNavigator.js:12)
in KeyboardAwareNavigator (at SceneView.js:9)
in SceneView (at StackViewLayout.tsx:900)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at StackViewCard.tsx:106)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at screens.native.js:100)
in Screen (at StackViewCard.tsx:93)
in Card (at createPointerEventsContainer.tsx:95)
in Container (at StackViewLayout.tsx:975)
in RCTView (at screens.native.js:131)
in ScreenContainer (at StackViewLayout.tsx:384)
in RCTView (at createAnimatedComponent.js:151)
in AnimatedComponent (at StackViewLayout.tsx:374)
in PanGestureHandler (at StackViewLayout.tsx:367)
in StackViewLayout (at withOrientation.js:30)
in withOrientation (at StackView.tsx:104)
in RCTView (at Transitioner.tsx:267)
in Transitioner (at StackView.tsx:41)
in StackView (at createNavigator.js:80)
in Navigator (at createKeyboardAwareNavigator.js:12)
in KeyboardAwareNavigator (at createAppContainer.js:430)
in NavigationContainer (at withExpoRoot.js:26)
in RootErrorBoundary (at withExpoRoot.js:25)
in ExpoRoot (at renderApplication.js:40)
in RCTView (at AppContainer.js:101)
in DevAppContainer (at AppContainer.js:115)
in RCTView (at AppContainer.js:119)
in AppContainer (at renderApplication.js:39)
我正在使用 React-native 在我的前端做这个项目。
**我的代码是这个 - 我的前端 **
App.js
import createAppContainer from 'react-navigation';
import createStackNavigator from 'react-navigation-stack';
import MealsScreen from './src/screens/Meals';
import Modal from './src/screens/Modal';
const AppNavigation = createStackNavigator(
Meals:
screen: MealsScreen
,
initialRouteName: 'Meals'
);
const RootStack = createStackNavigator(
Main: AppNavigation,
Modal: Modal,
,
mode: 'modal',
headerMode: 'none',
);
export default createAppContainer( RootStack );
膳食
import React from 'react';
import Text, View, StyleSheet, FlatList from 'react-native';
import ListItem from '../components/ListItem';
import UseFetch from '../hooks/useFetch';
const Meals = (navigation) =>
const loading, data: meals = UseFetch('https://serverless.mgyavega.now.sh/api/meals');
return(
<View style = styles.container >
loading ? <Text style = styles.text >Cargando por favor espere...</Text> :
<FlatList
style = styles.list
data = meals
keyExtractor= x => x.id
renderItem = ( item ) =>
<ListItem
onPress= () => navigation.navigate('Modal', id: item.id )
name = item.name
/>
/>
</View>
)
Meals.navigationOptions = (
title: 'Comidas Disponibles',
);
const styles = StyleSheet.create(
container:
flex: 1,
backgroundColor: '#fff',
alignItems: 'flex-start',
justifyContent: 'flex-start'
,
list:
alignSelf: 'stretch'
,
text:
flex: 1,
alignItems: 'center',
justifyContent: 'center'
);
export default Meals;
创建一个调用 Flatlist 操作的列表并管理我的列表中的信息。
List.js
import React from 'react';
import TouchableOpacity, Text, StyleSheet from 'react-native';
export default ( name, onPress ) =>
return (
<TouchableOpacity onPress = onPress style= styles.container >
<Text style = styles.text > name </Text>
</TouchableOpacity>
)
const styles = StyleSheet.create(
container:
paddingHorizontal: 15,
height: 60,
justifyContent: 'center',
borderBottomWidth: 1,
borderBottomColor: '#eee'
,
text:
fontSize: 16
);
获取我的项目的 url。
UseFecth.js
import useEffect, useState from 'react';
const UseFetch = ( url ) =>
const [loading, setLoading] = useState(true);
const [ data, setData] = useState([]);
const fetchData = async () =>
const response = await fetch(url);
const data = await response.json();
setData(data);
setLoading(false);
;
useEffect(() =>
fetchData();
, [] );
return loading, data
export default UseFetch;
我的 modal.js
import React from 'react';
import View, Text, from 'react-native';
import UseFetch from '../hooks/useFetch';
export default (navigation) =>
const id = navigation.getParam('_id');
const loading, data = UseFetch(`https://serverless.mgyavega.now.sh/api/meals/$id`);
console.log( 'Información del id del menú: ', id );
return (
loading ? <Text>Cargando </Text> :
<View>
<Text> </Text>
<Text> </Text>
</View>
)
我正在使用 MongoDB、Ziet 和 Node.js 做我的后端。
这是我的路线。
index.js
var express = require('express');
var mongoose = require('mongoose');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
var meals = require('./routes/meals');
var orders = require('./routes/orders');
mongoose.connect(process.env.MONGODB_URI, useNewUrlParser: true, useUnifiedTopology: true );
app.use('/api/meals', meals);
app.use('/api/orders', orders);
module.exports = app;
Meals.js
var express = require('express');
var Meals = require('../models/meals');
var router = express.Router();
router.get('/', ( req, res ) =>
Meals.find()
.exec()
.then( x =>
res.status(200).send(x)
);
);
router.get('/:id', ( req, res ) =>
Meals.findById(req.params.id)
.exec()
.then( x =>
res.status(200).send(x);
);
);
Models.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const Meal = mongoose.model('Meal', new Schema(
name: String,
desc: String,
));
module.exports = Meal;
我不知道为什么这些信息重复了我。
感谢您给予我的合作。
谢谢。
马里奥
【问题讨论】:
【参考方案1】:我最好的猜测是这条线产生了重复的密钥。
keyExtractor= x => x.id
【讨论】:
感谢您的帮助,我该怎么做才能使该行不重复,尝试删除它,但将以下错误卖给我。虚拟化列表:元素缺少键,请务必在每个元素中指定键或标识属性或提供自定义键提取器。【参考方案2】:在这一行中,keyExtractor= x => x.id id 可能已重复。 例如。 ["id":1,"name":"hello","id":1,"name":"world"] 两个值都有相同的 id。
如果列表中的所有值都是唯一的,请尝试 keyExtractor= x => x 否则,您可以使用列表中的任何属性。例如 .keyExtractor= x => x.name
【讨论】:
感谢您的帮助,请调查但我收到以下错误。 keyExtractor = x => x 警告:发现两个具有相同密钥的孩子,% s
。密钥必须是唯一的,组件才能在更新中保持其身份。非唯一键会导致孩子重复或省略;该行为不兼容,可能会在未来版本中更改。% S,[Object object],【参考方案3】:
使用数据库 ID 作为键的问题在于,根据您的查询,您的数据库可以返回具有重复 ID 的行。 我在我的项目中使用 uuid (https://www.npmjs.com/package/uuid),它就像一个魅力!
【讨论】:
这不是一个好主意。这将导致不必要的重新渲染。 react 需要唯一键而不是随机键是有原因的。【参考方案4】:如果有人有同样的事情,解决方案是最简单的。
在 keyExtractor = x => x.id 中,它用 keyExtractor = x => x._id 更改,因为在 mongoDB 数据库中,每条记录的 id 都是 _id ,因为我把它带来的 id 给了我这导致了重复。
其他都是正确的。
他希望他能帮助别人。
【讨论】:
以上是关于警告:列表中的每个孩子都应该有一个唯一的“key”属性。%s%s的主要内容,如果未能解决你的问题,请参考以下文章
添加了关键道具 ||警告:列表中的每个孩子都应该有一个唯一的“关键”道具
如何修复警告:列表中的每个孩子都应该有一个唯一的“关键”道具
警告:列表中的每个孩子在 React.js 中都应该有一个唯一的“key”道具