Flutter Web删除数据报RangeError索引越界错误如何解决
问题根因
这个RangeError索引越界是典型的遍历列表过程中修改原列表长度导致的问题:
你在for循环里用固定索引i遍历_inventoryListByPage,但await _clinicRemoveDevice执行时,方法内部直接改动了被遍历的_inventoryListByPage本身——常见情况是删除接口请求成功后,方法内直接调用setState把对应设备项从列表里移除、或是有数据监听器收到删除事件后自动刷新了这个列表为更短的新列表。
循环过程中列表长度不断变小,但索引i还是按初始的遍历逻辑累加,等i的值超过列表当前的最大有效下标时,就会直接抛出索引越界错误。你现在报错的位置虽然是打印_inventoryListByPage[i].deviceUID,但本质是这行执行时i已经不是合法的列表下标了。
排查步骤
- 给
_clinicRemoveDevice方法加断点,确认方法执行前后_inventoryListByPage.length的数值变化,就能直接看到是不是这个方法触发了列表长度修改。 - 在报错的print语句前加日志打印当前
i值和_inventoryListByPage.length,报错时你会看到i >= _inventoryListByPage.length,和错误描述完全匹配。
修复方案
优先选最稳妥的方案:遍历原列表的副本做删除逻辑,完全规避遍历过程中原列表变动的影响:
_deleteSelected() async { // 生成原列表的浅拷贝,遍历过程不受原列表改动干扰 final inventoryCopy = List.from(_inventoryListByPage); for (var i = 0; i < inventoryCopy.length; i++) { final currentItem = inventoryCopy[i]; if (currentItem.selected) { final uid = currentItem.deviceUID; if (uid != null && uid.isNotEmpty) { await _clinicRemoveDevice(0, uid); print(uid); } } } // 所有删除操作完成后,统一拉取最新列表数据刷新UI _getClinicInventory(''); }
其他可选优化方向:
- 不要在
_clinicRemoveDevice方法内部做列表修改操作,这个方法只负责发起删除接口请求、返回请求结果即可,列表刷新统一放到循环结束后做,从根源上避免遍历过程中列表结构变动。 - 可以先把所有选中的待删除设备UID提前收集到一个单独的列表里,再遍历这个待删UID列表做删除,逻辑更清晰,完全不会和原页面列表的状态耦合。
内容的提问来源于stack exchange,提问作者John Reaper
相关产品推荐
相关产品推荐

