所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

React二维数组怎么声明和使用?超详细实战教程帮你快速学会

React二维数组怎么声明和使用?超详细实战教程帮你快速学会 一

文章目录CloseOpen

先搞懂:React里二维数组的3种声明方式,每种都对应具体业务场景

声明二维数组不是“随便写个嵌套数组”就行,选对方式能少走80%的弯路。我 了3种覆盖90%业务场景的方法,你可以直接对号入座:

  • 字面量直接写——适合固定少量静态数据
  • 最直观的就是直接写二维数组字面量,比如做一个简单的商品价格表,数据就几个:

    const priceTable = [
    

    ['商品名称', '单价(元/斤)', '库存(斤)'], // 表头

    ['红富士苹果', 12, 500],

    ['广东香蕉', 8, 800],

    ['广西沃柑', 15, 300]

    ];

    我刚开始写的时候,总爱把每个子数组写得密密麻麻,结果后来朋友要加“产地”字段,我找了三分钟才找到对应的子项—— 你如果子数组项数超过3个,一定要给每个子项加注释,比如:

    const priceTable = [
    

    ['商品名称', '单价(元/斤)', '库存(斤)'], // [名称, 单价, 库存]

    ['红富士苹果', 12, 500], // [名称, 单价, 库存]

    ['广东香蕉', 8, 800], // [名称, 单价, 库存]

    ];

    这种方式的优点是“直观到不用想”,缺点是“只适合静态数据”——如果你的数据要从后端拿,或者需要批量生成,千万别用这个,不然改数据时能烦死你。

  • 循环生成——适合动态固定行列的空数据
  • 如果要做“可编辑的空表格”(比如让用户填5行3列的订单明细),总不能手动写5个子数组吧?这时候用循环生成最高效。我常用Array.from配合map,比如生成5行3列的空表格:

    const emptyOrderTable = Array.from({ length: 5 }, () => Array(3).fill(''));
    

    // 结果:[[ '', '', '' ], [ '', '', '' ], ...](共5行)

    这里有个新手必踩的大坑:别用Array.fill填充引用类型(比如对象、数组)!我之前做问卷组件时,想生成5行2列的“问题+答案”空数据,写了这么一段:

    // 错误示例:fill填充对象会导致“浅拷贝”
    

    const wrongEmptyData = Array.from({ length: 5 }, () => Array(2).fill({ value: '' }));

    // 改第一个子项的value,结果整列都变了!

    wrongEmptyData[0][0].value = '问题1';

    console.log(wrongEmptyData[1][0].value); // 输出'问题1',这显然不对

    后来查文档才知道,fill对引用类型是“共享同一个对象”,所有子项都会跟着变。正确做法是用函数返回新对象

    // 正确示例:每次返回新对象,避免浅拷贝
    

    const rightEmptyData = Array.from({ length: 5 }, () =>

    Array(2).fill(null).map(() => ({ value: '' }))

    );

    // 改第一个子项,其他不变

    rightEmptyData[0][0].value = '问题1';

    console.log(rightEmptyData[1][0].value); // 输出'',对了!

    这种方式适合“批量生成固定结构的空数据”,比如可编辑表格、问卷组件,效率比手动写高10倍。

  • 接口数据转——适合后端返回的业务数据
  • 大部分业务里,后端返回的是对象数组(比如商品列表),而我们的组件需要二维数组(比如表格只显示“名称、单价、库存”),这时候用map转一下就行:

    // 后端返回的对象数组
    

    const productList = [

    { id: 1, name: '红富士苹果', price: 12, stock: 500, category: '水果' },

    { id: 2, name: '广东香蕉', price: 8, stock: 800, category: '水果' }

    ];

    // 转成二维数组:只保留需要的字段

    const tableData = productList.map(item => [item.name, item.price, item.stock]);

    // 结果:[['红富士苹果',12,500], ['广东香蕉',8,800]]

    我之前做订单管理系统时,后端返回的字段有15个,但表格只需要5个,我就用这种方式按需筛选字段——别把所有字段都塞进去,不然二维数组会很臃肿,渲染时费性能不说,后期改数据还得找半天。

    为了让你更清楚怎么选,我做了个对比表格,直接看就能选对:

    声明方式 适用场景 优点 注意事项
    字面量直接写 固定少量静态数据(如简单价格表) 直观简单,开发快 子项多需加注释,避免混乱
    循环生成 动态生成固定行列的空数据(如可编辑表格) 高效批量生成,减少重复代码 避免用fill填充引用类型(对象/数组)
    接口数据转 后端数据适配业务组件(如商品列表表格) 贴合业务,数据灵活 按需筛选字段,避免冗余

    再学会:二维数组的3个核心使用场景,直接解决业务问题

    声明完二维数组,关键是要用对——我 了3个最常遇到的场景,每个都有对应的解决技巧,都是我踩过坑才摸透的:

  • 渲染嵌套列表——用两层map,别忘加key
  • 用二维数组渲染表格或嵌套列表,必须用两层map:外层map渲染行,内层map渲染单元格。比如渲染前面的priceTable(商品价格表),正确写法是:

    const PriceTable = () => {
    

    const priceTable = [

    ['商品名称', '单价(元/斤)', '库存(斤)'],

    ['红富士苹果', 12, 500],

    ['广东香蕉', 8, 800]

    ];

    return (

    {priceTable.map((row, rowIndex) => ( // 外层key用行索引(或数据唯一值) {row.map((cell, colIndex) => ( // 内层key用列索引(或数据唯一值) ))} ))}
    {cell}

    );

    };

    我之前写的时候,总忘给trtdkey,结果控制台警告跳个不停——key是React用来识别元素变化的,必须加。如果你的数据里有唯一值(比如商品id),最好用唯一值当key,比如key={item.id},比用索引更稳定(我之前用索引当key,排序后元素位置乱了,改成id就好了)。

  • 修改二维数组的元素——必须保持immutable,否则组件不更新
  • 这是新手最容易踩的坑!我去年帮朋友改商品规格表时,就犯过:直接改原数组的某个元素,结果页面没反应。比如:

    // 错误示例:直接修改原数组,React检测不到变化
    

    const [specTable, setSpecTable] = useState([['S', 10], ['M', 12]]);

    // 想把M的价格改成15,直接改原数组

    specTable[1][1] = 15;

    setSpecTable(specTable); // 页面没反应!

    后来查React文档才知道,React的状态更新是“浅比较”——如果前后状态是同一个引用(比如原数组),React会认为状态没变化,不会重新渲染。正确做法是返回新数组,用map复制并修改:

    // 正确示例:用map复制新数组,保持immutable
    

    const updateSpecPrice = (rowIndex, colIndex, newPrice) => {

    setSpecTable(prev => {

    // 外层map复制行

    return prev.map((row, rIdx) => {

    if (rIdx === rowIndex) {

    // 内层map复制列,修改目标单元格

    return row.map((cell, cIdx) => cIdx === colIndex ? newPrice cell);

    }

    // 没变化的行直接返回原对象(性能更好)

    return row;

    });

    });

    };

    // 调用:把第二行(index=1)第二列(index=1)改成15

    updateSpecPrice(1, 1, 15);

    这个方法我用了半年,从来没遇到过状态不更新的问题。你可以直接复制这个函数,改成自己的业务逻辑——比如改商品名称,就把newPrice换成newName

  • 状态管理——用useState存二维数组,初始化给默认值
  • 在React里,二维数组作为状态,得用useState存。我 你初始化时给一个符合业务场景的默认值,比如做可编辑表格,默认给一行空数据:

    // 默认一行三列的空数据
    

    const [orderTable, setOrderTable] = useState([['', '', '']]);

    别给null或者undefined,不然渲染时要做非空判断(比如orderTable && orderTable.map(...)),麻烦得很。 如果你需要批量修改状态(比如清空表格),可以直接设置新数组:

    // 清空表格,恢复默认一行三列
    

    setOrderTable([['', '', '']]);

    我当初学这些的时候,光是改二维数组的状态就试了5种方法,最后才找到immutable的正确姿势。你要是按上面的步骤试了,比如用循环生成做了个空表格,或者用map改了个单元格,欢迎回来评论区告诉我效果!对了,要是你还有其他二维数组的问题,比如怎么排序或者过滤,也可以留个言,我下次再写篇详细的教程帮你解决~


    React里用字面量声明二维数组适合什么场景?

    适合固定少量的静态数据场景,比如简单的商品价格表、基础信息表格这种数据量少且不会频繁变动的情况。比如做一个显示3-5种商品名称、单价和库存的表格,直接写二维数组字面量就很直观。不过要注意,如果子数组的项数超过3个,最好给每个子项加注释,比如标注“[名称, 单价, 库存]”,不然后期改数据时找对应项会很麻烦——我之前写过没加注释的表格,后来加字段找了三分钟才找到位置。

    循环生成二维数组时要避免什么坑?

    千万别用Array.fill填充引用类型(比如对象、数组)!我之前做问卷组件时,想生成5行2列的空数据,用了fill({value: ”}),结果改第一个子项的value,整列都跟着变了——因为fill对引用类型是“共享同一个对象”,所有子项都会联动。正确的做法是用函数返回新对象,比如用map生成每个子项:Array.from({length:5}, () => Array(2).fill(null).map(() => ({value: ”}))),这样每个子项都是独立的,不会互相影响。

    修改二维数组元素后组件没反应怎么办?

    这是因为直接修改了原数组,React的状态更新是“浅比较”,如果前后状态是同一个引用,React会认为没变化。解决办法是保持“不可变(immutable)”,用map复制新数组再修改——比如要改某行某列的值,就外层map复制行,内层map复制列,只修改目标单元格。我去年帮朋友改商品规格表时就踩过这个坑,直接改原数组页面纹丝不动,改成map复制新数组后立马生效了。

    渲染二维数组的嵌套列表时为什么要加key?

    key是React用来识别元素变化的标记,要是不加会控制台警告,还可能导致元素位置混乱。比如渲染表格时,外层tr用行索引当key,内层td用列索引当key,或者用数据里的唯一值(比如商品id)更稳定——我之前忘加key,控制台警告不停,后来加上索引就好了;再后来用商品id当key,排序后元素位置也没乱过。

    后端返回的对象数组怎么转成React需要的二维数组?

    用map就能转,按需筛选需要的字段就行。比如后端返回的是商品对象数组,每个对象有name、price、stock等字段,你可以用productList.map(item => [item.name, item.price, item.stock]),把对象里的关键信息取出来组成子数组。这样转出来的二维数组刚好贴合表格、嵌套列表等组件的需求,还能避免数据冗余——我做商品列表表格时就这么转,数据灵活又符合业务逻辑。

    原文链接:https://www.mayiym.com/51570.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码