Ionic + React.js:警告:列表中的每个孩子都应该有一个唯一的“关键”道具

Posted

技术标签:

【中文标题】Ionic + React.js:警告:列表中的每个孩子都应该有一个唯一的“关键”道具【英文标题】:Ionic + React.js: Warning: Each child in a list should have a unique "key" prop 【发布时间】:2020-12-03 08:41:05 【问题描述】:

我将 firebase 用于数据库,将 Ionic + React 用于移动应用程序。我已经将我的 firebase 数据转换为数组,但是当我想映射这些值时。它告诉我它应该有一个唯一键,但我已经在元素的返回函数中放置了一个唯一键。有人能告诉我我做错了什么吗?谢谢。

这是我将对象转换为数组的代码

const Tab2: React.FC = () => 
  const [doctors, setDoctor] = React.useState([]);

  useIonViewWillEnter(()=>
    console.log('Enter')
    firebase.database().ref('users').orderByChild('type').equalTo('doctor').on('value',(snapshot)=>
          setDoctor(Object.keys(snapshot.val()).map(key => ( [key]: snapshot.val()[key] )))
        )
    console.log(doctors)

  )

我的回报

        <IonList>
        doctors.map(elem => 
            return(
              <IonItem key=elem['uid']>
              <IonLabel>
                <IonText className="font-weight: bold;">
                <h3>elem['name']</h3>
                </IonText>
                <h4>elem['speciality']</h4>
                <h4>elem['email']</h4>
              </IonLabel>
              <br></br>
            </IonItem> 
            )
          )
        </IonList>

我得到的是Warning: Each child in a list should have a unique "key" prop.

我的火力基地结构

更新:console.log(doctors) 只会输出一个像 [] 这样的空数组,我不知道为什么。在组件进入之前,我已经把它放在一个方法中了。

【问题讨论】:

【参考方案1】:

注意:这只是一个警告,而不是错误。

这是正确的方法。

<IonList>
  doctors.map((elem, index) => 
    // index has to come from the second parameter from map
    
    return (
      <IonItem key=index>
        <IonLabel>
          <IonText className="font-weight: bold;">
            <h3>elem["name"]</h3>
          </IonText>
          <h4>elem["speciality"]</h4>
          <h4>elem["email"]</h4>
        </IonLabel>
        <br></br>
      </IonItem>
    );
  )
</IonList>;

索引必须放在第一个/父 div 元素中。在这种情况下,它将是&lt;IonItem&gt;

参考:https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Array/map

另外,你没有得到数据。像这样调整你的代码。您只需要创建一个新的 arr,然后通过快照来获取密钥。

将具有相应键的对象推送到新的 arr,因此它可以在没有特定键名的情况下进行迭代,例如 eA9w5ynhqN9iT7kKDBt2Ane9VF3

useIonViewWillEnter(() => 
  console.log("Enter");
  let newArr = [];
  firebase
    .database()
    .ref("users")
    .orderByChild("type")
    .equalTo("doctor")
    .on("value", (snapshot) => 
      let key;
      snapshot.forEach((childSnap) => 
        key = childSnap.key; // im just getting the key
        const snapVal = snapshot.val(); // getting the object
        newArr.push(snapVal[key]); 
      );
      setDoctor(newArr);

      // console.log(doctors)
    );
);

【讨论】:

谢谢先生,它没有出错,但console.log(doctors) 正在记录[],即使我把它放在ionViewWIllEnter 中,也许数组还没有填充? &lt;IonList&gt;之前的return方法之前放一个console.log(doctors)并分享你得到的东西。 酷,我知道问题是什么,请在帖子中发布您的数据形状:) 简而言之,必须删除 iae... 键。 您是什么意思,先生?我们可以聊聊这件事吗? 所以复制粘贴结果,并在问题中发布代码【参考方案2】:

尝试将 key 属性添加到每个子元素以及子元素中的每个元素,它会起作用。

您的代码应如下所示:

<IonList>
    doctors.map(elem => 
        return(
          <IonItem key=elem['uid']>
          <IonLabel key="lbl-" + elem['uid']>
            <IonText key="txt-"+elem['uid']className="font-weight: bold;">
            <h3 key="name-"+elem['uid']>elem['name']</h3>
            </IonText>
            <h4 key="speciality-"+elem['uid']>elem['speciality']</h4>
            <h4 key="email-"+elem['uid']>elem['email']</h4>
          </IonLabel>
          <br></br>
        </IonItem> 
        )
      )
</IonList>

如果你注意到我在键之前添加了 lbl-, txt- 以避免另一个警告: "警告:flattenChildren(...):遇到两个孩子用同一个key,

【讨论】:

您是什么意思,先生?可以举个例子吗?

以上是关于Ionic + React.js:警告:列表中的每个孩子都应该有一个唯一的“关键”道具的主要内容,如果未能解决你的问题,请参考以下文章

警告:列表中的每个孩子都应该有一个唯一的“关键”道具。反应.js

警告不会出现在Ionic 2中的(点击)或(点击)事件中

如何在(Ionic + React.js App)中自动聚焦 IonInput/OtpInput 字段,我已经尝试了所有解决方案

在 ionic v1 中的每一天的特定时间发送通知

在ionic2中使用图像和文本加载延迟列表

如何从 React.js 中的多个输入输入字段创建列表?