如何基于查询条件在嵌套JSON数组的指定索引位置插入数据
解决方案
1. 指定位置插入数据实现
你可以通过findIndex获取各层级的索引值,再调用splice方法完成指定位置插入,示例代码如下:
const queryNew = { district: "Kolkata", ward: "6", category: "grievance", insertIndex: 1 // 此处可替换为用户实际指定的插入位置索引 }; const data = { serial_number: "0034", name: "Donny Van De Beek" }; // 找到对应区县的索引 const districtIndex = testData.findIndex(v => v.district === queryNew.district); if (districtIndex !== -1) { // 找到对应 ward 的索引 const wardIndex = testData[districtIndex].ward_no.findIndex(v => v.ward === queryNew.ward); if (wardIndex !== -1) { const targetArray = testData[districtIndex].ward_no[wardIndex][queryNew.category]; // 执行插入:splice(插入位置, 删除元素数量, 待插入数据),删除数量为0即纯插入操作 targetArray.splice(queryNew.insertIndex, 0, data); } }
如果你需要根据已有数据的字段确定插入位置,比如插入到serial_number为0002的条目之后,可以额外增加一步索引查找:
const insertAfterSerial = "0002"; const targetInsertIndex = targetArray.findIndex(v => v.serial_number === insertAfterSerial) + 1; targetArray.splice(targetInsertIndex, 0, data);
2. React 重复插入问题修复
重复插入是因为你把数据修改逻辑直接写在了组件渲染函数中,React 每次重渲染都会执行这段逻辑,导致数据被重复添加。修复方案如下:
- 数据修改逻辑放到
useEffect钩子中,添加空依赖数组保证仅组件挂载时执行一次 - 不要直接修改导入的原始JSON数据,深拷贝一份再操作避免污染原始数据源
修复后的代码:
import React, { useEffect, useState } from "react"; import originTestData from './testData.json'; const Display = () => { // 把原始数据存到state中,避免污染导入的原始数据 const [testData, setTestData] = useState([]); useEffect(() => { // 深拷贝原始数据 const dataCopy = JSON.parse(JSON.stringify(originTestData)); const queryNew = { district: "Kolkata", ward: "6", category: "grievance", insertIndex: 1 }; const insertData = { serial_number: "0034", name: "Donny Van De Beek" }; const districtIndex = dataCopy.findIndex(v => v.district === queryNew.district); if (districtIndex !== -1) { const wardIndex = dataCopy[districtIndex].ward_no.findIndex(v => v.ward === queryNew.ward); if (wardIndex !== -1) { const targetArray = dataCopy[districtIndex].ward_no[wardIndex][queryNew.category]; targetArray.splice(queryNew.insertIndex, 0, insertData); } } setTestData(dataCopy); console.log(dataCopy); }, []); return( <div></div> ); } export default Display;
内容的提问来源于stack exchange,提问作者coolhack7
相关产品推荐
相关产品推荐

