【问题标题】:Each child should have a unique key prop每个孩子都应该有一个唯一的钥匙道具
【发布时间】:2021-08-07 04:26:27
【问题描述】:

我正在为一个看起来像这样的纸牌游戏制作反应大厅: Lobby Image

每个名称和“踢”按钮都是我根据名称列表呈现的反应组件(此列表中的所有名称都是唯一的)。我认为由于名称是唯一的,我可以使用名称作为键,但由于某种原因,我收到以下错误: Error Message

我在这里做错了什么?

注意:我还尝试对 KickButton 键执行 key = {player + "1"} 以使其在其各自的 PlayerIcon 中唯一,但错误仍然存​​在

import React from 'react';
import firebase from "./firebase.js";

class PlayerIcon extends React.Component{

    render() {
        return(
            <div>
                <h1>{this.props.name}</h1>
            </div>
        )
    }
}

class KickButton extends React.Component {
    constructor(props){
        super();
        this.state = {
            style: props.style,
            player: props.kicked,
            Lobbycode: props.Lobbycode
        }
        this.handleKick = this.handleKick.bind(this)
    }

    handleKick() {
        var firestore = firebase.firestore();  
        var docRef = firestore.doc("Games/Game " + this.state.Lobbycode);
        const confirmed = window.confirm("Do you want to kick " + this.state.player + "?");
        if (confirmed) {
            docRef.get()
                .then((docSnapshot) => {
                    if (docSnapshot.data().PlayerAmnt === 1) {
                        firestore.doc("Games/Active Games").update({
                            "Active Games" : firebase.firestore.FieldValue.arrayRemove(this.state.Lobbycode)
                        })
                        firestore.doc("Games/Game " + this.state.Lobbycode).delete();
                    } else {
                        docRef.update({
                            players : firebase.firestore.FieldValue.arrayRemove(this.state.player),
                            PlayerAmnt : firebase.firestore.FieldValue.increment(-1)
                        }) 
                    }
                })
            return;
        }
    }

    render(props) {
        return <button onClick = {this.handleKick} style = {this.state.style}>Kick</button>
    }
}

class HostLobbylist extends React.Component {

    render() {
        var playerstorender = [<div style={{display: "flex"}}><PlayerIcon key={this.props.players[0]} name={this.props.players[0]}/></div>].concat(
            this.props.players.slice(1).map(player => 
                <div style={{display: "flex"}}>
                <PlayerIcon key={player} name={player}/><KickButton key={player} kicked={player} style={{fontSize: "20px", height: "30px", verticalAlign: "middle", margin:"25px"}} Lobbycode={this.props.Lobbycode}/>
            </div>))

    return(
        <div>
            {playerstorender} 
        </div>   
    ) 
}
}

export default HostLobbylist

编辑 1:下面是我的新渲染函数,其中键位于父 div 中,但错误仍然存​​在。我还是误会了吗?

class HostLobbylist extends React.Component {

 render() {
     var playerstorender = [<div key={this.props.players[0]} style={{display: "flex"}}><PlayerIcon name={this.props.players[0]}/></div>].concat(
         this.props.players.slice(1).map(player => 
             <div key={player} style={{display: "flex"}}>
             <PlayerIcon name={player}/><KickButton kicked={player} style={{fontSize: "20px", height: "30px", verticalAlign: "middle", margin:"25px"}} Lobbycode={this.props.Lobbycode}/>
         </div>))

 return(
     <div>
         {playerstorender} 
     </div>   
 ) 
}
}

编辑 2:我发现了错误!!!! this.props.players 有时有 0 个项目,所以我猜玩家中第一个要渲染的项目的关键是未定义的。感谢您的帮助!

【问题讨论】:

  • key需要在return的父元素中,而不是在PlayerIcon组件上。 .map(player =&gt;&lt;div key={player} style={{display: "flex"}}&gt;&lt;PlayerIcon name={player}/&gt;...
  • @pilchard 我的编辑显示了我的新渲染,但错误仍然存​​在,我还是做错了什么吗?
  • player 是一个对象吗?还是字符串值?
  • @HichamELBSI 它是一个字符串值
  • @HichamELBSI 我发现了错误,感谢您为我指出正确的方向!

标签: javascript reactjs


【解决方案1】:

您可以添加一个在每个循环中递增的索引,并使用此索引作为键来区分您的元素和循环

this.props.players.slice(1).map((player, index) => 
                <div key={index} style={{display: "flex"}}>

【讨论】:

  • Index as key 是一个很差的建议,只会在以后数组顺序发生变化时导致头疼。问题还在于 OP 将键放在子元素而不是父 div 上。文档中也不推荐,除非万不得已。
  • 我同意@pilchard。键应该是唯一的 id,而不是索引
  • 你可以做 Marc 写的,并通过使用 key={player.name} 而不是索引来改进,因为你有一个唯一的名字
  • 好吧,如果他们从不重新排列数组中的项目,例如排序,那么使用索引作为键是没有问题的。
猜你喜欢
  • 2022-11-11
  • 2023-01-19
  • 2021-06-12
  • 1970-01-01
  • 2022-11-25
  • 2019-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多