正文从这开始~

总览

当我们从map()方法返回的两个或两个以上的元素具有相同的key属性时,会产生"Encountered two children with the same key"错误。为了解决该错误,为每个元素的key属性提供独一无二的值,或者使用索引参数。

这里有个例子来展示错误是如何发生的。

// App.js
const App = () => {
// ️ name property is not a unique identifier
const people = [
{id: 1, name: 'Alice'},
{id: 2, name: 'Bob'},
{id: 3, name: 'Alice'},
]; /**
* ️ Encountered two children with the same key, `Alice`.
* Keys should be unique so that components maintain their identity across updates.
* Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.
*/
return (
<div>
{people.map(person => {
return (
<div key={person.name}>
<h2>{person.id}</h2>
<h2>{person.name}</h2>
</div>
);
})}
</div>
);
}; export default App;

上述代码片段的问题在于,我们在每个对象上使用name属性作为key属性,但是name属性在整个对象中不是独一无二的。

index

解决该问题的一种方式是使用索引。它是传递给map方法的第二个参数。

const App = () => {
const people = [
{id: 1, name: 'Alice'},
{id: 2, name: 'Bob'},
{id: 3, name: 'Alice'},
]; // ️ now using index for key
return (
<div>
{people.map((person, index) => {
return (
<div key={index}>
<h2>{person.id}</h2>
<h2>{person.name}</h2>
</div>
);
})}
</div>
);
}; export default App;

我们传递给Array.map方法的函数被调用,其中包含了数组中的每个元素和正在处理的当前元素的索引。

索引保证是唯一的,但是用它来做key属性并不是一个最好的做法。因为它不稳定,在渲染期间会发生变化。

唯一标识

更好的解决方案是,使用一个能唯一标识数组中每个元素的值。

在上面的例子中,我们可以使用对象上的id属性,因为每个id属性保证是唯一的。

// App.js
const App = () => {
const people = [
{id: 1, name: 'Alice'},
{id: 2, name: 'Bob'},
{id: 3, name: 'Alice'},
]; // now using the id for the key prop
return (
<div>
{people.map(person => {
return (
<div key={person.id}>
<h2>{person.id}</h2>
<h2>{person.name}</h2>
</div>
);
})}
</div>
);
}; export default App;

使用id作为key属性好多了。因为我们保证了对象id属性为1时,name属性总是等于Alice

React使用我们传递给key属性的值是出于性能方面的考虑,以确保它只更新在渲染期间变化的列表元素。

当数组中每个元素都拥有独一无二的key时,React会更容易确定哪些列表元素发生了变化。

你可以使用index作为key属性。然而,这可能会导致React在幕后做更多的工作,而不是像独一无二的id属性那样稳定。

尽管如此,除非你在渲染有成千上万个元素的数组,否则你很有可能不会注意到使用索引和唯一标识符之间有什么区别。

React报错之Encountered two children with the same key的更多相关文章

  1. react 报错的堆栈处理

    react报错 Warning: You cannot PUSH the same path using hash history 在Link上使用replace 原文地址https://reactt ...

  2. vue使用v-for时vscode报错 Elements in iteration expect to have 'v-bind:key' directives

    vue使用v-for时vscode报错 Elements in iteration expect to have 'v-bind:key' directives Vue 2.2.0+的版本里,当在组件 ...

  3. 【spring boot】使用定时任务@Scheduled 报错:Encountered invalid @Scheduled method 'dealShelf': Cron expression must consist of 6 fields (found 7 in "0 30 14 * * ? *")

    在spring boot中使用使用定时任务@Scheduled 报错: org.springframework.beans.factory.BeanCreationException: Error c ...

  4. React报错 :browserHistory doesn't exist in react-router

    由于版本问题,React中history不可用 import { hashHistory } from 'react-router' 首先应该导入react-router-dom包: import { ...

  5. react报错 TypeError: Cannot read property 'setState' of undefined

    代码如下: class test extends Component { constructor(props) { super(props); this.state = { liked: false ...

  6. React报错之Cannot find name

    正文从这开始~ .tsx扩展名 为了在React TypeScript中解决Cannot find name报错,我们需要在使用JSX文件时使用.tsx扩展名,在你的tsconfig.json文件中把 ...

  7. React报错之Cannot find namespace context

    正文从这开始~ 总览 在React中,为了解决"Cannot find namespace context"错误,在你使用JSX的文件中使用.tsx扩展名,在你的tsconfig. ...

  8. React报错之Expected `onClick` listener to be a function

    正文从这开始~ 总览 当我们为元素的onClick属性传递一个值,但是该值却不是函数时,会产生"Expected onClick listener to be a function" ...

  9. React报错:Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix,

    今天在开发时报了以下错误,记录一下 我们不能在组件销毁后设置state,防止出现内存泄漏的情况 出现原因直接告诉你了,组件都被销毁了,还设置个锤子的state啊 解决方案: 利用生命周期钩子函数:co ...

随机推荐

  1. 【摸鱼神器】一次搞定 vue3的 路由 + 菜单 + tabs

    做一个管理后台,首先要设置路由,然后配置菜单(有时候还需要导航),再来一个动态tabs,最后加上权限判断. 这个是不是有点繁琐?尤其是路由的设置和菜单的配置,是不是很雷同?那么能不能简单一点呢?如果可 ...

  2. 【仿真】Carla介绍与基本使用 [1] (附代码 基础版)

    0. 参考与前言 主要介绍无人驾驶的仿真环境CARLA,开源社区维护,以下为相关参考链接: Carla官方文档 建议后续找的时候 先按好版本号,有些功能/api 是新版本里有的 Carla官方gith ...

  3. A* K短路

    注:\(A*\) 求解K短路效率极其低下,时间复杂度\(O(nklog\ n)\),空间视题目而定,因为本质是爆搜,可求解数据范围较小的题目. 我们使用\(A*\)求解k短路: 首先需要预处理出估价函 ...

  4. 网易数帆 Envoy Gateway 实践之旅:坚守 6 年,峥嵘渐显

    服务网格成熟度不断提升,云原生环境下流量处理愈发重要, Envoy Gateway 项目于近日宣布开源,"旨在大幅降低将 Envoy 作为 API 网关的使用门槛",引发了业界关注 ...

  5. Java包机制和JavaDoc

    目录 包机制 JavaDoc 视频课程 包机制 包的本质就是文件夹 为了更好的组织类, Java提供了包机制, 用于区别类名的命名空间, 使项目看起来更加整洁 一般公司庸域名倒置作为包名 为了能够使用 ...

  6. 可变参数——JavaSE基础

    可变参数 方法声明中,在指定参数类型后加一个省略号...即可声明可变参数 可变参数必须是参数列表的最后一个参数 声明 public void test(int... i){ System.out.pr ...

  7. PostgreSQL Array 数组类型与 FreeSql 打出一套【组合拳】

    前言 PostgreSQL 是世界公认的功能最强大的开源数据库,除了基础数据类型 int4/int8/varchar/numeric/timestamp 等数据类型,还支持 int4[]/int8[] ...

  8. 第6章 字符串(上)——C风格字符串

    6.1 C-strings(C 风格字符串) C风格字符串: 字符数组是元素为字符型的数组,字符串是以空字符'\0' 作为数组最后一个元素的字符数组. 如果指定了数组的大小,而字符串的长度又小于数组大 ...

  9. ExtJS 布局-Absolute布局(Absolute layout)

    更新记录: 2022年5月31日 发布本篇 1.说明 使用xy配置项设置子组件在父容器中绝对位置,本质是将子组件的CSS的position设置为absolute,然后使用x和y配置项映射到CSS的to ...

  10. UiPath循环活动Do While的介绍和使用

    一.Do While的介绍 先执行循环体, 再判断条件是否满足, 如果满足, 则再次执行循环体, 直到判断条件不满足, 则跳出循环 二.Do While在UiPath中的使用 1. 打开设计器,在设计 ...