React列表子元素需唯一key警告:已知外层设key仍存疑问
解决React列表key属性警告问题
嘿,我一眼就瞅出问题所在啦!你收到的这个警告,核心原因是React要求map方法返回的每一项最顶层元素必须带有唯一的key属性,而你现在把key加在了内层的<div className={styles.post}>上,可map实际返回的是包裹它的那个外层空<div>——React根本没读到这个正确的key!
问题出在代码里的这部分:
你当前的map返回结构是:
return ( <div> {/* 这是map返回的最顶层元素,没有key! */} <div key={shortid.generate()} className={ styles.post }> {/* ... 帖子内容 ... */} </div> </div> );
两种快速修复方案:
方案1:把key移到最外层div上
直接将key属性放到map返回的根节点上:
return ( <div key={shortid.generate()}> {/* key移到这里 */} <div className={ styles.post }> <Link href={ url } className={ styles.postLink } target="_blank"> {imgUrl !== 'undefined' && <div className={ styles.postImageContainer }><img className={ styles.postImage } src={ imgUrl } /></div>} <div className={ styles.postInfo }> <p className={ styles.postName }> { name.length < 40 ? name : name.substring(0, 40).trim() + '...' } </p> {startDate !== 'undefined' && <p className={ styles.postDate }><Moment format="DD/MM/YYYY">{ startDate }</Moment> - <Moment format="DD/MM/YYYY">{ endDate }</Moment></p>} </div> </Link> </div> </div> );
方案2:去掉多余的外层div(更推荐)
其实那个外层空div完全是多余的,直接返回带key的帖子容器就行,还能简化DOM结构:
return ( <div key={post.id} className={ styles.post }> {/* 用post.id当key更靠谱! */} <Link href={ url } className={ styles.postLink } target="_blank"> {imgUrl !== 'undefined' && <div className={ styles.postImageContainer }><img className={ styles.postImage } src={ imgUrl } /></div>} <div className={ styles.postInfo }> <p className={ styles.postName }> { name.length < 40 ? name : name.substring(0, 40).trim() + '...' } </p> {startDate !== 'undefined' && <p className={ styles.postDate }><Moment format="DD/MM/YYYY">{ startDate }</Moment> - <Moment format="DD/MM/YYYY">{ endDate }</Moment></p>} </div> </Link> </div> );
额外小建议:
尽量用数据本身的唯一标识(比如post.id)来当key,而不是用shortid.generate()生成的临时key。因为生成的key每次组件渲染都会变化,React没法复用列表项组件,会影响性能;而用数据自带的唯一ID,只要数据不变key就不变,是React官方推荐的最佳实践。当然如果你的post.id确实不唯一,再用shortid也没问题~
内容的提问来源于stack exchange,提问作者BennKingy
相关产品推荐
相关产品推荐

