ReactJS - " Keys"在循环中添加组件时出错

时间:2017-07-25 16:36:41

标签: reactjs

我正在学习如何使用TIC TAC TOE示例构建React的教程,我发现它非常有趣。

在本教程结束时,我发现了以下挑战之一:

  

重写Board以使用两个循环来制作正方形而不是硬编码。

这是原始render方法

render() {
    return (
        <div>
            <div className="board-row">
                {this.renderSquare(0)}
                {this.renderSquare(1)}
                {this.renderSquare(2)}
            </div>
            <div className="board-row">
                {this.renderSquare(3)}
                {this.renderSquare(4)}
                {this.renderSquare(5)}
            </div>
            <div className="board-row">
                {this.renderSquare(6)}
                {this.renderSquare(7)}
                {this.renderSquare(8)}
            </div>
        </div>
    );
}

我第一次只用了一个循环,一切都运行得很好

render() {
    let col_count = 3;
    let row_count = 3;

    let rows = [];
    for (var i = 0; i < row_count; i++) {
        rows.push(
            <div key={i} className="board-row">
                {this.renderSquare(i*col_count + 0)}
                {this.renderSquare(i*col_count + 1)}
                {this.renderSquare(i*col_count + 2)}
            </div>
        );
    }

    return (
        <div>{rows}</div>

    );
}

但后来我尝试用2个循环编码:

render() {
    let col_count = 3;
    let row_count = 3;

    let rows = [];
    for (var i = 0; i < row_count; i++) {
        let cols = [];
        for (var j = 0; j < col_count; j++) {
            cols.push(this.renderSquare(i*col_count + j));
        }

        rows.push(
            <div key={i} className="board-row">{cols}</div>
        );
    }

    return (
        <div>{rows}</div>

    );
}

我开始得到着名的&#34;键&#34;控制台上出错:

  

警告:数组或迭代器中的每个子节点都应该有一个唯一的&#34;键&#34;支柱。检查Board的呈现方法。

所以现在我想知道:我错过了什么?当我刚刚使用一个循环时,行仍然有效的密钥ID。并且每行中的列来自另一个始终有效的渲染方法。

第二次实施的问题在哪里? 我怎么能实现它以便我没有得到那个错误?

更新

如果需要,这是renderSquare

renderSquare(i) {
    return (
        <Square
            value={this.props.squares[i]}
            onClick={() => this.props.onClick(i)}
        />
    );
}

2 个答案:

答案 0 :(得分:1)

我相信您会看到警告,因为在您的第二次实施中,您还有 cols 数组,该数组基本上是 Square 的列表的。所以你的代码是这样的:

render() {
    let col_count = 3;
    let row_count = 3;

    let rows = [];
    for (var i = 0; i < row_count; i++) {
        let cols = [];
        for (var j = 0; j < col_count; j++) {
            cols.push(this.renderSquare(i*col_count + j));
        }

        rows.push(
            <div key={i} className="board-row">
                <Square/> //needs key
                <Square/> //needs key
            </div>
        );
    }

    return (
        <div>{rows}</div>

    );
}

答案 1 :(得分:1)

我认为您的renderSquare(i) { return ( <Square key={i} value={this.props.squares[i]} onClick={() => this.props.onClick(i)} /> ); } 组件需要密钥。

<!-- Navigation -->
<div id="gxcpl" class="navbar navbar-default navbar-fixed-top" role="navigation">
    <div class="container">
        <div class="navbar-header">
            <a class="navbar-brand hidden-lg hidden-md" href="#">Living Ahimsa</a>
            <a class="hidden-sm hidden-xs" href="#">
                <img class="gxcpl-logo" src="assets/images/logo.png" />
            </a>
            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-menubuilder">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="collapse navbar-collapse navbar-menubuilder">
            <ul class="nav navbar-nav navbar-left">
                <li class="active"><a href="/">Home</a></li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> Bio Homes</a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Introduction</a></li>
                        <li><a href="#">Innovation</a></li>
                        <li><a href="#">Services</a></li>
                        <li><a href="#">Development</a></li>
                        <li><a href="#">Future</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> Bio Energy</a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">BIO Heating</a></li>
                        <li><a href="#">BIO Lighting</a></li>
                        <li><a href="#">BIO Air</a></li>
                        <li><a href="#">BIO Frequency</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> Bio Water</a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Whole House Filter</a></li>
                        <li><a href="#">Reverse Osmosis</a></li>
                        <li><a href="#">Portable Filters</a></li>
                        <li><a href="#">Portable Storage</a></li>
                        <li><a href="#">Rain Water Storage</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> Bio Garden</a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Bio Grow System</a></li>
                        <li><a href="#">Bio Watering System</a></li>
                        <li><a href="#">Indoor Growing</a></li>
                        <li><a href="#">Organic Seeds</a></li>
                        <li><a href="#">Organic Plants</a></li>
                    </ul>
                </li>
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> Bio Health</a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Core Health</a></li>
                        <li><a href="#">Oils</a></li>
                        <li><a href="#">Raw Foods</a></li>
                        <li><a href="#">Natural Supplements</a></li>
                        <li><a href="#">Protien</a></li>
                    </ul>
                </li>
            </ul>
            <ul class="nav navbar-nav navbar-right">
                <li class="dropdown">
                    <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-angle-down"></i> <i class="fa fa-user-o"></i></a>
                    <ul class="dropdown-menu" role="menu">
                        <li><a href="#">Shopping Basket</a></li>
                        <li><a href="#">Contact Us</a></li>
                        <li><a href="#">Call Request</a></li>
                        <li><a href="#">Account Settings</a></li>
                        <li><a href="#">Login/Register</a></li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
</div>
<!-- Navigation -->