【问题标题】:Warning: Each child in an array or iterator should have a unique "key" prop.; key prop already added in li警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”属性。 li 中已经添加了 key 道具
【发布时间】:2017-06-17 19:47:30
【问题描述】:

在将 key 属性添加到 TodoItems 中的 li 项目后,我收到此警告:

警告:数组或迭代器中的每个孩子都应该有一个唯一的“key”道具。查看TodoItems的render方法

我有以下页面:

<!DOCTYPE html>
<html>

<head>
    <title>todo-list</title>
    <script src="https://unpkg.com/react@15.3.2/dist/react.js"></script>
    <script src="https://unpkg.com/react-dom@15.3.2/dist/react-dom.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/4.0.0-beta.3/react-router.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/fixed-data-table/0.6.3/fixed-data-table.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/fixed-data-table/0.6.3/fixed-data-table.min.css" rel="stylesheet">

    <head>


        <body>
            <div style="margin-bottom: 35px">
                <a class="nav-link" href="/clock">clock</a>
                <a class="nav-link" href="/counter">counter</a>
                <a class="nav-link" href="/data-table-basic">data-table-basic</a>
                <a class="nav-link" href="/query-params-react-router">query-params-react-router</a>
                <a class="nav-link" href="/todo-list">todo-list</a>
                <a class="nav-link" href="/validated-form">validated-form</a>
            </div>


            <p>
                <a href="https://www.kirupa.com/react/simple_todo_app_react.htm" target="_blank">The tutorial link</a>
            </p>

            <div id="entry"></div>


            <script>
                function determineMode(filepath) {
                    var modeString = "ace/mode/" + filepath;
                    return modeString;
                }
            </script>

            <script src="/static/ace-builds2/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>

            <script>
                var editor = ace.edit("editor");
                editor.getSession().setMode(determineMode('html'));
                editor.session.setNewLineMode("unix");
                editor.setTheme("ace/theme/monokai");
                editor.setFontSize(15);
            </script>

            <script type="text/babel">
                var destination = document.querySelector("#entry"); var TodoItems = React.createClass({ createTasks: function(item){ return this.props.entries.map(item => { return (
                <li data-bind-thisthing={item.key} key={item.key}>
                    <span>{item.text + " "} </span>
                    <a href="#" data-id="{item.id}" className="remove-filter" onClick={()=> this.props.remove(item)}
                        >
                            remove
                        </a>
                </li>
                ) }); }, render: function(){ return (
                <ul className="theList">
                    {this.createTasks()}
                </ul>
                ); } }); var TodoList = React.createClass({ getInitialState: function(){ return { items: [ 'If user clicks add button and input is empty, set a red border and focus the input box', 'Allow interactive DOM update of component when user edits code box', 'Allow categories for things like angular2, knockout, etc', 'Allow user to save new code snippets after starting in a sandbox', ] }; }, addItem: function(e) { var itemArray = this.state.items; if (this._inputElement.value.length > 0){ itemArray.push( { text: this._inputElement.value, key: this.state.items.length } ); this._inputElement.value = ""; this.setState({ items: itemArray }) } e.preventDefault(); }, // removing items from a list // http://stackoverflow.com/questions/27817241/how-to-remove-an-item-from-a-list-with-a-click-event-in-reactjs removeItem: function(item){ var items = this.state.items.filter(function(itm){ return item.key !== itm.key; }); this.setState({ items: items }); }, render: function() { return (
                <div className="todoListMain">
                    <div className="header">
                        <form onSubmit={this.addItem}>
                            <input ref={(a)=> this._inputElement = a} placeholder="enter task" />
                            <button type="submit">add</button>
                        </form>
                    </div>
                    <TodoItems remove={this.removeItem} entries={this.state.items} />
                </div>
                ); } }); ReactDOM.render(
                <div>
                    <TodoList/>
                </div>, destination );

            </script>
        </body>

</html>

奇怪的问题通常看起来像this 范围问题。

【问题讨论】:

  • 最初 items 包含字符串。他们既没有 text 也没有 key 属性。这就是为什么您会看到有关重复键和“未定义”作为输出的警告。顺便说一句,因为用户可以删除元素,所以在将项目添加为唯一键时不能使用数组长度。
  • 不确定,但我猜keys 被react 用来查询虚拟dom。因此元素是通过循环添加的,您将多次绑定相同的结构。因此,您需要添加 key 以便 react 可以区分它们
  • 检查密钥是否重复。

标签: javascript html reactjs


【解决方案1】:

问题是 TodoList 的初始状态。 createTasks 函数需要 entries (props) 一个包含对象的数组,其中每个对象应具有键 idtextkey 但它正在获取包含字符串的数组。

【讨论】:

    猜你喜欢
    • 2018-04-29
    • 2019-01-15
    • 2018-05-22
    • 2017-02-23
    • 2017-02-03
    • 1970-01-01
    • 2020-09-06
    • 2019-03-18
    相关资源
    最近更新 更多