警告:数组或迭代器中的每个子代都应具有唯一的“键".支柱 [英] Warning: Each child in an array or iterator should have a unique "key" prop

查看:65
本文介绍了警告:数组或迭代器中的每个子代都应具有唯一的“键".支柱的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

G'Day. 我想遍历一堆JSON对象,然后将它们变成React Elements.这些对象看起来像这样

G'Day. I want to iterate over a bunch of JSON objects and turn them into React Elements. The objects look like this

                                "fields":
                                    [
                                        {   
                                            key: "testname",
                                            "name": "testname",
                                            "altName": "",
                                            "visible": true,
                                            "groupVisibility": "public",
                                            "type": "text",
                                            "component": "input",
                                            "label": "Test Smart Input",
                                            "placeholder": "Some default Value",
                                            "required": "required",
                                            "validated": false,
                                            "data": []
                                        },
                                        {   
                                            key: "password",
                                            "name": "password",
                                            "altName": "",
                                            "visible": true,
                                            "groupVisibility": "public",
                                            "type": "password",
                                            "component": "input",
                                            "label": "Test Smart Input",
                                            "placeholder": "Password",
                                            "required": "required",
                                            "validated": false,
                                            "data": []
                                        }
                                    ]

遍历它们的代码非常简单.这样的:

And the code that iterates over them is quite simple. Such:

//--------------------
formFields(fieldsIn) {


    const fieldsOut = [];                                           // ARRAY of FORM ELEMENTS to return
    console.log('doin fields');
    for (var fieldIn in fieldsIn) {                                 // array of FORM ELEMENT descriptions in JSON
        console.log(fieldIn);
        let field = React.createElement(SmartRender,                // go build the React Element 
                                        fieldIn,
                                        null);                      // lowest level, no children, data is in props     
        console.log('doin fields inside');
        fieldsOut.push(field);
    }
    return(fieldsOut);                                              // this ARRAY is the children of each PAGE
}

我得到了错误 警告:数组或迭代器中的每个子代都应具有唯一的键"道具. 有什么提示吗? 干杯

And I get the error Warning: Each child in an array or iterator should have a unique "key" prop. Any hints? Cheers

我更改了代码以执行此操作.

I changed the code to do this.

//--------------------
formFields(fieldsIn) {


    const fieldsOut = [];                                           // ARRAY of FORM ELEMENTS to return
    console.log('doin fields');
    for (var fieldIn in fieldsIn) {                                 // array of FORM ELEMENT descriptions in JSON
        console.log(fieldIn);
        let field = React.createElement(SmartRender,                // go build the React Element 
                                        {key: fieldsIn[fieldIn].name, fieldIn},
                                        null);                      // lowest level, no children, data is in props     
        console.log('doin fields inside');
        fieldsOut.push(field);
    }
    return(fieldsOut);                                              // this ARRAY is the children of each PAGE
}

我得到同样的错误.我不明白为什么! 固定的!谢谢您的帮助.

And I get the same error. I don't understand why! Fixed! Thanks for the help.

这是代码.

    //--------------------
    formFields(fieldsIn) {


        const fieldsOut = [];                                           // ARRAY of FORM ELEMENTS to return
        for (var fieldIn in fieldsIn) {                                 // array of FORM ELEMENT descriptions in JSON
            console.log(fieldIn);
            let field = React.createElement(SmartRender,                // go build the React Element 
                                            {key: fieldsIn[fieldIn].key, fieldIn},
                                            null);                      // lowest level, no children, data is in props     
            fieldsOut.push(field);
        }
        return(fieldsOut);                                              // this ARRAY is the children of each PAGE
    }


    //----------------------
    pages(pagesIn, format) {

        // I tried to do this in JSX, but no syntax I wrestled with would
        // allow me to access the childred when building this with the
        // BABEL transpiler.  Same goes for the METHOD just above, items().
        //
        // This method returns an array of pages this are React elements
        // this are treated as children by the smartForm.

        const pagesOut = [];                                            // array of pages to build and return
        let Section = {};                                               // Component to fire in the build
        switch(format) {
            case 'accordion': {
                Section = AccordionSection;
                break;
            }
            case 'workflow': {
                Section = null;                                         // I haven't written this yet
                break;
            }
            case 'simple': {
                Section = null;                                         // I haven't written this yet
                break;
            }
        }

        for (var pageIn in pagesIn) {                                   // pages, any format, any number 1..N
            let children = this.formFields(pagesIn[pageIn].fields);     // 1..N fields, we don't know beforehand 
            let page = React.createElement( Section, 
                                            pagesIn[pageIn].props, 
                                            children);
            pagesOut.push(page);
        }
        return(pagesOut);                                               // this ARRAY is the children of each FORM
    }



    //--------
    render() {

        let formIn  = this.props.form;                                  // JSON description of FORM
        let formOut = null;                                             // contructed REACT/Javascript form


        switch (formIn.format) {                                        // what type of operation is this
            case 'accordion': {                                         // Accordion in a FORM, OK
                let children = this.pages(formIn.pages,
                                          formIn.format);               // build the children
                formOut = React.createElement(Accordion,                // construct the parent with ALL nested CHILDREN after
                                            {key: formIn.formName},     // just a unique key 
                                            children);                  // N ACCORDION pages, N2 input fields
                break;
            }
            case 'workflow': {
                let children = this.pages(formIn.pages,                 // build the children
                                          formIn.format);               // build the children
                formOut = React.createElement(Workflow,                 // and create the complex sheet element
                                            { key: formIn.formName},
                                            children);                  // N SLIDING pages, N2 input fields
                break;
            }
            case 'simple': {
                let children = this.pages(formIn.pages,                 // build the children
                                          formIn.format);               // build the children
                formOut = React.createElement(Simple,
                                            { key: formIn.formName},
                                            children);                  // One page, N input fields
            break;
            }
        }

        return(
                <div>
                    <h2>SmartForm Parser</h2>
                    <p>"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
                    {formOut}
                </div>
        );
    }
}
//-------------------------------------------------------------------------
export default SmartForm;

//-----------------   EOF -------------------------------------------------

推荐答案

您需要向React元素添加一个唯一的key prop.

You need to add a unique key prop to your React element.

根据 反应文档 :

According to the React docs:

Keys帮助React识别哪些项目已更改,添加或为 删除.键应赋予数组内的元素以给出 这些元素具有稳定的身份.

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity.

选择键的最佳方法是使用唯一标识的字符串 兄弟姐妹中的一个列表项.大多数情况下,您会使用自己的ID 数据作为键

The best way to pick a key is to use a string that uniquely identifies a list item among its siblings. Most often you would use IDs from your data as keys

如果您对呈现的项目没有稳定的ID,则可以使用 项目索引是万不得已的关键

When you don’t have stable IDs for rendered items, you may use the item index as a key as a last resort

您可以这样做

for (var fieldIn in fieldsIn) {                                 // array of FORM ELEMENT descriptions in JSON
        console.log(fieldIn);
        let field = React.createElement(SmartRender,                // go build the React Element 
                                        {key: fieldsIn[fieldIn].key, fieldIn},
                                        null);                      // lowest level, no children, data is in props     
        console.log('doin fields inside');
        fieldsOut.push(field);
    }

为什么需要按键?

默认情况下,在DOM节点的子节点上递归时,React只会同时遍历两个子节点列表,并在存在差异时生成一个变异.

By default, when recursing on the children of a DOM node, React just iterates over both lists of children at the same time and generates a mutation whenever there’s a difference.

例如,在子级末尾添加元素时,在这两棵树之间进行转换会很好:

For example, when adding an element at the end of the children, converting between these two trees works well:

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>first</li>
  <li>second</li>
  <li>third</li>
</ul>

React将匹配两棵<li>first</li>树,匹配两棵<li>second</li>树,然后插入<li>third</li>树.

React will match the two <li>first</li> trees, match the two <li>second</li> trees, and then insert the <li>third</li> tree.

如果您天真地实现它,则在开始处插入元素会降低性能.例如,在这两棵树之间进行转换效果很差.

If you implement it naively, inserting an element at the beginning has worse performance. For example, converting between these two trees works poorly.

<ul>
  <li>first</li>
  <li>second</li>
</ul>

<ul>
  <li>third</li>
  <li>first</li>
  <li>second</li>
</ul>

那是派上用场的键了.

这篇关于警告:数组或迭代器中的每个子代都应具有唯一的“键".支柱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆