首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在React Native App中得到警告“列表中的每个孩子都应该有一个唯一的关键道具”

在React Native App中得到警告“列表中的每个孩子都应该有一个唯一的关键道具”
EN

Stack Overflow用户
提问于 2021-09-09 07:43:52
回答 3查看 44关注 0票数 0

我现在正在学习React Native,我不能理解每次运行我的测试项目时弹出的警告。请帮助我找到它的解决方案。

下面是我正在尝试实现的代码:

代码语言:javascript
复制
const {width: screenWidth} = Dimensions.get('screen');
// screen width Multiply by 0.8

const Footer = () => {
  return (
    <View>
      <Text style={{color: '#fff', fontSize: 20}}>Reviews</Text>
      <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 20}}>
        <Image
          source={require('../assets/five-stars.png')}
          style={{width: 90, height: 18}}
        />
        <Text style={{marginLeft: 10}}>& Up</Text>
      </View>
      <View style={{flexDirection: 'row', marginTop: 30}}>
        <TouchableOpacity
          style={{
            backgroundColor: '#525252',
            width: 200,
            paddingTop: 20,
            paddingBottom: 20,
            alignItems: 'center',
            borderTopLeftRadius: 22,
          }}>
          <Text>Reset</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={{
            backgroundColor: '#00ACED',
            width: 200,
            alignItems: 'center',
            paddingTop: 20,
            paddingBottom: 20,
            borderTopRightRadius: 23,
          }}>
          <Text>Apply</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const renderItem = ({item: {title, data, key}}) => (
  <View>
    <Text style={styles.headingText}>{title}</Text>
    <View style={styles.item}>
      {data.map(el => (
        <TouchableOpacity
          style={[
            {
              backgroundColor: el.isCheck ? '#00ACED' : 'transparent',
              padding: 20,
              borderColor: '#185268',
              borderWidth: 2,
              borderRadius: 40,
            },
          ]}>
          <Text style={styles.btnText}>{el.name}</Text>
        </TouchableOpacity>
      ))}
    </View>
  </View>
);

const SandboxScreen = () => {
  const [isModalVisible, setModalVisible] = useState(false);
  const [data, setData] = useState([
    {
      key: 'id-1',
      title: 'Workshop Category',
      data: [
        {name: 'BodyShops', isCheck: false, key: 'id-5'},
        {name: 'Electric Cars', isCheck: true, key: 'id-6'},
        {name: 'Performance Shops', isCheck: false, key: 'id-7'},
      ],
    },
    {
      key: 'id-2',
      title: 'Vehicle Category',
      data: [
        {name: 'Cars', isCheck: false, key: 'id-8'},
        {name: 'Trucks', isCheck: true, key: 'id-9'},
        {name: 'Motorbikes', isCheck: false, key: 'id-10'},
      ],
    },
    {
      key: 'id-3',
      title: 'Services',
      data: [
        {name: 'Accident Repair', isCheck: false, key: 'id-11'},
        {name: 'AC System Diagnosis', isCheck: false, key: 'id-12'},
        {name: 'Car Polishing / Detailing', isCheck: false, key: 'id-13'},
        {name: 'Electric / Hybrid System Repair', isCheck: true, key: 'id-14'},
        {name: 'General Mechanical Work', isCheck: true, key: 'id-15'},
      ],
    },
    {
      key: 'id-4',
      title: 'Brands',
      data: [
        {name: 'FORD', isCheck: false, key: 'id-16'},
        {name: 'BMW', isCheck: false, key: 'id-17'},
        {name: 'BMW', isCheck: false, key: 'id-18'},
        {name: 'AUDI', isCheck: false, key: 'id-19'},
        {name: 'JAGUAR', isCheck: false, key: 'id-20'},
        {name: 'FERRARI', isCheck: true, key: 'id-21'},
        {name: 'LAMBORGHINI', isCheck: false, key: 'id-22'},
      ],
    },
  ]);

  const toggleModal = () => {
    setModalVisible(prevState => !prevState);
  };

  return (
    <View
      style={[
        {
          flex: 1,
          backgroundColor: '#252525',
        },
      ]}>
      <View style={styles.container}>
        <FlatList
          data={data}
          renderItem={renderItem}
          keyExtractor={item => item.key}
          ListFooterComponent={Footer}
        />
      </View>

      {/* <Button title="Show modal" onPress={toggleModal} />

      <Modal
        isVisible={isModalVisible}
        animationIn="slideInRight"
        animationOut="slideOutRight"
        animationInTiming={500}
        animationOutTiming={500}
        hasBackdrop={true}
        backdropColor="#252525"
        backdropOpacity={0.8}
        backdropTransitionInTiming={500}
        backdropTransitionOutTiming={500}
        onBackdropPress={() => setModalVisible(false)}
        style={{alignItems: 'flex-end', margin: 0}}>
        <View
          style={{
            backgroundColor: 'white',
            flex: 1,
            paddingTop: 50,
            width: screenWidth * 0.7,
          }}>
          <View style={styles.container}>
            <FlatList
              data={DATA}
              renderItem={renderItem}
              keyExtractor={item => item.id}
            />
          </View>
        </View>
      </Modal> */}
    </View>
  );
};

export default SandboxScreen;

这个错误出现在我的应用程序的最底部,我想不出解决它的方法。请帮助我在上面的代码中查找错误,我提供了这些代码作为参考。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-09-09 07:55:12

当你这样做时,看看这个链接:https://reactjs.org/docs/lists-and-keys.html#keys

代码语言:javascript
复制
    const renderItem = ({item: {title, data, key}}) => (
  <View>
    <Text style={styles.headingText}>{title}</Text>
    <View style={styles.item}>
      {data.map(el => (
        <TouchableOpacity
          style={[
            {
              backgroundColor: el.isCheck ? '#00ACED' : 'transparent',
              padding: 20,
              borderColor: '#185268',
              borderWidth: 2,
              borderRadius: 40,
            },
          ]}>
          <Text style={styles.btnText}>{el.name}</Text>
        </TouchableOpacity>
      ))}
    </View>
  </View>
);

你的列表中没有任何关键的道具。

你可以像这样添加:

代码语言:javascript
复制
    const renderItem = ({item: {title, data, key}}) => (
  <View>
    <Text style={styles.headingText}>{title}</Text>
    <View style={styles.item}>
      {data.map(el => (
        <TouchableOpacity
          key={el.key}
          style={[
            {
              backgroundColor: el.isCheck ? '#00ACED' : 'transparent',
              padding: 20,
              borderColor: '#185268',
              borderWidth: 2,
              borderRadius: 40,
            },
          ]}>
          <Text style={styles.btnText}>{el.name}</Text>
        </TouchableOpacity>
      ))}
    </View>
  </View>
);

或者那种风格的东西。这应该可以解决你的问题。

票数 0
EN

Stack Overflow用户

发布于 2021-09-09 07:52:07

React必须跟踪作为数组传递的子元素,例如{someArray.map(e => <SomeComponent/>)}。若要仅更新已更改的子项,并且不会在其中一个更改时重新渲染所有子项,则应将标识key属性添加到由映射函数返回的顶级元素:

代码语言:javascript
复制
<View style={styles.item}>
    {data.map(el =>
        <TouchableOpacity key={el.key}
            {/* ... */}
        </TouchableOpacity>
    )}
</View>
票数 2
EN

Stack Overflow用户

发布于 2021-09-09 07:50:26

你可以试试这个

代码语言:javascript
复制
const {width: screenWidth} = Dimensions.get('screen');
// screen width Multiply by 0.8

const Footer = () => {
  return (
    <View>
      <Text style={{color: '#fff', fontSize: 20}}>Reviews</Text>
      <View style={{flexDirection: 'row', alignItems: 'center', marginTop: 20}}>
        <Image
          source={require('../assets/five-stars.png')}
          style={{width: 90, height: 18}}
        />
        <Text style={{marginLeft: 10}}>& Up</Text>
      </View>
      <View style={{flexDirection: 'row', marginTop: 30}}>
        <TouchableOpacity
          style={{
            backgroundColor: '#525252',
            width: 200,
            paddingTop: 20,
            paddingBottom: 20,
            alignItems: 'center',
            borderTopLeftRadius: 22,
          }}>
          <Text>Reset</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={{
            backgroundColor: '#00ACED',
            width: 200,
            alignItems: 'center',
            paddingTop: 20,
            paddingBottom: 20,
            borderTopRightRadius: 23,
          }}>
          <Text>Apply</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const renderItem = ({item: {title, data, key}}) => (
  <View>
    <Text style={styles.headingText}>{title}</Text>
    <View style={styles.item}>
      {data.map(el => (
        <TouchableOpacity
          key={el.key} // add key here
          style={[
            {
              backgroundColor: el.isCheck ? '#00ACED' : 'transparent',
              padding: 20,
              borderColor: '#185268',
              borderWidth: 2,
              borderRadius: 40,
            },
          ]}>
          <Text style={styles.btnText}>{el.name}</Text>
        </TouchableOpacity>
      ))}
    </View>
  </View>
);

const SandboxScreen = () => {
  const [isModalVisible, setModalVisible] = useState(false);
  const [data, setData] = useState([
    {
      key: 'id-1',
      title: 'Workshop Category',
      data: [
        {name: 'BodyShops', isCheck: false, key: 'id-5'},
        {name: 'Electric Cars', isCheck: true, key: 'id-6'},
        {name: 'Performance Shops', isCheck: false, key: 'id-7'},
      ],
    },
    {
      key: 'id-2',
      title: 'Vehicle Category',
      data: [
        {name: 'Cars', isCheck: false, key: 'id-8'},
        {name: 'Trucks', isCheck: true, key: 'id-9'},
        {name: 'Motorbikes', isCheck: false, key: 'id-10'},
      ],
    },
    {
      key: 'id-3',
      title: 'Services',
      data: [
        {name: 'Accident Repair', isCheck: false, key: 'id-11'},
        {name: 'AC System Diagnosis', isCheck: false, key: 'id-12'},
        {name: 'Car Polishing / Detailing', isCheck: false, key: 'id-13'},
        {name: 'Electric / Hybrid System Repair', isCheck: true, key: 'id-14'},
        {name: 'General Mechanical Work', isCheck: true, key: 'id-15'},
      ],
    },
    {
      key: 'id-4',
      title: 'Brands',
      data: [
        {name: 'FORD', isCheck: false, key: 'id-16'},
        {name: 'BMW', isCheck: false, key: 'id-17'},
        {name: 'BMW', isCheck: false, key: 'id-18'},
        {name: 'AUDI', isCheck: false, key: 'id-19'},
        {name: 'JAGUAR', isCheck: false, key: 'id-20'},
        {name: 'FERRARI', isCheck: true, key: 'id-21'},
        {name: 'LAMBORGHINI', isCheck: false, key: 'id-22'},
      ],
    },
  ]);

  const toggleModal = () => {
    setModalVisible(prevState => !prevState);
  };

  return (
    <View
      style={[
        {
          flex: 1,
          backgroundColor: '#252525',
        },
      ]}>
      <View style={styles.container}>
        <FlatList
          data={data}
          renderItem={renderItem}
          keyExtractor={item => item.key}
          ListFooterComponent={Footer}
        />
      </View>

     <Button title="Show modal" onPress={toggleModal} />

      <Modal
        isVisible={isModalVisible}
        animationIn="slideInRight"
        animationOut="slideOutRight"
        animationInTiming={500}
        animationOutTiming={500}
        hasBackdrop={true}
        backdropColor="#252525"
        backdropOpacity={0.8}
        backdropTransitionInTiming={500}
        backdropTransitionOutTiming={500}
        onBackdropPress={() => setModalVisible(false)}
        style={{alignItems: 'flex-end', margin: 0}}>
        <View
          style={{
            backgroundColor: 'white',
            flex: 1,
            paddingTop: 50,
            width: screenWidth * 0.7,
          }}>
          <View style={styles.container}>
            <FlatList
              data={DATA}
              renderItem={renderItem}
              keyExtractor={item => item.key} // change id to key
            />
          </View>
        </View>
      </Modal>
    </View>
  );
};

export default SandboxScreen;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69114187

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档