映射数组时如何为 React 子级指定键

Posted

技术标签:

【中文标题】映射数组时如何为 React 子级指定键【英文标题】:How to specify a key for React children when mapping over an array 【发布时间】:2016-08-26 17:43:50 【问题描述】:

我在反应联系人列表组件中有一个方法,我正在返回另一个组件。我已经让它工作了,但我很好奇是否有更好的方法来构建我如何使用密钥。

具体来说 - 我从下面的方法中询问这行代码(数据被硬编码为示例以开始使用):

return <ShortContact contact=contact key=contact.id/>

这是上下文中的代码:

_getContacts() 
    let contactList = [
        
            id: 1,
            fName: "aaa",
            lName: "aaaaa",
            imgUrl: "http://brainstorminonline.com/wp-content/uploads/2011/12/blah.jpg",
            email: "aaa@aaaa.com",
            phone: "999999999999"
        ,
        
            id: 2,
            fName: "bbbbb",
            lName: "bbbbbbb",
            imgUrl: "https://media.licdn.com/mpr/mpr/shrinknp_200_200/bbb.jpg",
            email: "bbb@bbb-bbb.com",
            phone: "888888888888"
        ,
        
            id: 3,
            fName: "Number",
            lName: "Three",
            imgUrl: "http://3.bp.blogspot.com/-iYgp2G1mD4o/TssPyGjJ4bI/AAAAAAAAGl0/UoweTTF1-3U/s1600/Number+3+Coloring+Pages+14.gif",
            email: "three@ccccc.com",
            phone: "333-333-3333"
        
    ];

    return contactList.map((contact) => 
        "use strict";
        return <ShortContact contact=contact key=contact.id/>
    );

ShortContact 组件渲染:

class ShortContact extends React.Component 
    render() 
        return (
            <div >
                <li className="contact-short well whiteBG">
                    <img  className="contact-short-thumb" src=this.props.contact.imgUrl/>
                    <p className="contact-short-name">this.props.contact.fName</p><br />
                    <p className="contact-short-email">this.props.contact.email</p>
                </li>
            </div>
        );
    

我为如何使它工作而苦苦挣扎,却没有收到警告Warning: Each child in an array or iterator should have a unique "key" prop. 但是我想知道语法或结构是否有效以及是否应该重构。

【问题讨论】:

【参考方案1】:

这段代码没有任何问题。密钥是必需的,以便 react 知道如何渲染子节点。事实上,你的实现正是 react 需要程序员做的。现在可以更改使用哪个键等的详细信息,但看起来您已经有了最高效的解决方案。

主要要求是密钥是唯一的,只要 contact.id 始终是唯一的(如果它来自数据库,那么它将是唯一的)那么你就可以了。

或者,您可以在地图上使用索引作为键,但我不建议这样做(我将在下面的代码 sn-p 后解释)。

contactList.map((contact, i) => 
    return <ShortContact contact=contact key=i/>
);

我个人认为你的方法是最好的方法,因为它可以防止额外的渲染。我的意思是,例如,当从服务器返回一个新联系人时,每个联系人行都会被重新渲染,因为每个联系人的数组中的索引是不同的(假设你没有把它当作一个堆栈)......在该索引处具有新联系人数据的不同索引将导致重新渲染。因为 contact.id 是一个静态数字,如果该联系人的数据没有改变,那么 react 不会重新渲染它。

【讨论】:

谢谢!我对 React 很陌生 - 有时听到与我实际编写的代码相关的原因会产生很大的不同。 @MaryCamacho 非常欢迎您!你有正确的方法,这正是 react 的用途! :) 好工作。如果您还有任何问题或想了解更多,请随时提问,我会尽力解释:) 谢谢! - 实际上我还有另一个问题 - 因为为了在同一页面上添加创建联系表单 - 我需要将我的数据向上移动到父组件......这是新问题:***.com/questions/36991994/… 您不应该使用索引作为键值。 @joetidee 这不是我在帖子中所说的吗?从技术上讲,你可以它是一种替代方法,但我说不推荐。【参考方案2】:

需要使用唯一的密钥。在您的示例中,使用 id 是理想的。有关详细信息,请参阅以下内容:

https://facebook.github.io/react/docs/lists-and-keys.html

【讨论】:

以上是关于映射数组时如何为 React 子级指定键的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 React 中的嵌套对象数组进行映射

对象作为 React 子级无效(发现:[object Promise])

React 中的数组与键值对(映射/对象)

如何在没有 ID 的 React 中映射数组?

为孩子提供属性时如何为 React.cloneElement 分配正确的类型?

React Redux 在映射状态后获取 NaN