React18 渲染列表与添加key值
创始人
2024-03-06 07:41:45
0次

引用原作者链接:渲染列表

文章目录

  • 一、列表渲染
  • 二、警告

一、列表渲染

现在,有这样一组数据,需要在页面中呈现:

const students = ['孙悟空', '猪八戒', '沙和尚'];

如果想直接显示,可以直接将数组插入到JSX中,JSX会自动对数组展开并显示。但这样一来数据知识直接显示,不会添加任何的结构。如果希望将数组中的元素放到一个无序列表中显示,就需要对列表做一些处理了。

  • 孙悟空
  • 猪八戒
  • 沙和尚

可以使用for循环对其进行处理:

const students = ['孙悟空', '猪八戒', '沙和尚'];
const items = [];
​
for(let i=0; iitems.push(
  • {stus[i]}
  • ); } ​ const ele =
      {items}

    上边操作的本质其实就是根据一个旧数组students生成了一个新数组items:

    const students = ['孙悟空', '猪八戒', '沙和尚'];
    const items = [
  • 孙悟空
  • ,
  • 猪八戒
  • ,
  • 沙和尚
  • , ];

    这个操作我们也可以通过map()方法来完成:

    const students = ['孙悟空', '猪八戒', '沙和尚'];
    const items = students.map(item => 
  • {item}
  • ); const ele =
      {items}

    map()本身就是一个函数,所以我们完全可以直接将函数调用写在JSX中间:

    const students = ['孙悟空', '猪八戒', '沙和尚'];
    const ele = 
      {students.map(item =>
    • {item}
    • )}

    很显然使用map()比使用for循环要优雅很多,所以这也是我们在React中的常用方式。

    二、警告

    输出一个列表时,无论我们使用的for循环还是map()方法,当你打开控制台时你一定会看到一行红色的内容,它大概内容是:Warning: Each child in a list should have a unique “key” prop.

    Warning表示一个警告,警告表示它并不是一个特别严重的错误,但你最好把它处理了,所以当你在React项目中看到这个玩意的时候一定一定要想办法去除掉它。

    为什么会报出这个警告呢?事情要往前回溯一下,我们已经知道React是通过虚拟DOM来操作元素的,而React为了提升操作的性能,在DOM发生变化时只会去修改那些发生了变化的元素,这样就大大的减少了DOM操作从而提升了页面渲染的速度。

    React怎么知道哪些元素发生变化呢?其实也不难,React每次渲染都会生成一个由React元素构成的树(当然这棵树也对应着一课DOM元素构成的树,但是这里不太重要),React每次重新渲染都会生成一个新的React元素树,在页面刷新前,React会通过内部的diff算法对两个树中的React元素进行比较,并且找到那些发生变化的元素,并将他们的变化在真实的DOM元素上体现出来。

    这个算法听上去很神奇,其实很简单就是按照顺序比较两个元素,第一个和第一个比,第二个和第二个比,没有变化就放过,有变化就记录。

    扯了这么一长串,和上边的警告有什么关系吗?上边的例子中,我们把一个数组直接在JSX中呈现了出来。当我们第一次渲染时,列表可能是这样的:

    • 孙悟空
    • 猪八戒
    • 沙和尚

    假使数组发生了变化(这里还没讲怎么变,想象一下吧!),页面需要重新渲染,变成了这样:

    • 孙悟空
    • 猪八戒
    • 沙和尚
    • 唐僧

    这里我们在列表的最后增加了一个唐僧,那么前边的元素顺序是不变的,孙悟空第一个,猪八戒第二,沙和尚第三。所以这里在应用修改时只会修改最后一个li,对前边的三个不会有任何影响!性能非常棒!

    但是,加入唐僧不想在最后,它想去第一个位置,像这样:

    • 唐僧
    • 孙悟空
    • 猪八戒
    • 沙和尚

    这时问题就来了,唐僧第一,孙悟空第二…换句话说,所有元素的顺序都变了,那么React在比较元素不同时,它并不能知道孙悟空从第一变到了第二个,它会任务是唐僧替换了孙悟空,孙悟空替换了猪八戒,猪八戒替换了沙和尚,然后又增加了一个沙和尚,导致页面渲染是四个li都被重新渲染了!如果列表里有100个元素,那么就是100个都得重新渲染,性能不好!

    那么这种情况,我们就需要让React知道谁是孙悟空,谁又是唐僧。在React内部就设定了一个key属性,key属性可以作为React元素的唯一标识,和html中id类似。在创建一个列表时,我们可以为列表的每一个元素指定一个唯一的key,React就可以根据key而不是位置来比较元素,这样一来无论元素的位置如何改变,都不会导致过多的元素渲染,因为有了key以后,React就不再通过位置来比较两个元素了。

    上边的例子可以这样修改:

    const students = ['孙悟空', '猪八戒', '沙和尚'];
    const ele = 
      {students.map(item =>
    • item}>{item}
    • )}

    添加了key属性以后警告就消失了,设置key还有一些要求:

    • key必须在当前列表的元素中是唯一的
    • 一个元素的key最好是固定的
    • key不需要全局唯一,只需在当前列表中唯一即可。

    元素的key最好是固定的,这里直接举个反例,有些场景我们会使用元素的索引为key像这种:

    const students = ['孙悟空', '猪八戒', '沙和尚'];
    const ele = 
      {students.map((item, index) =>
    • index}>{item}
    • )}

    上例中,使用了元素的索引(index)作为key来使用,但这有什么用吗?没用!因为index是根据元素位置的改变而改变的,当我们在前边插入一个新元素时,所有元素的顺序都会一起改变,那么它和React中按顺序比较有什么区别吗?没有区别!而且还麻烦了,唯一的作用就是去除了警告。所以我们开发的时候偶尔也会使用索引作为key,但前提是元素的顺序不会发生变化,除此之外不要用索引做key。

    相关内容

    热门资讯

    前端-session、jwt 目录:   (1)session (2&#x...
    linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
    关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
    前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
    nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
    JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
    无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
    fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
    常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
    <C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...