You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中AsyncStorage mergeItem数组对象不兼容报错排查

Hey,我来帮你拆解这个问题——你遇到的mergeItem失败本质是两个问题叠加:代码里的变量名错误,加上mergeItem本身不支持数组结构的存储。咱们一步步来搞定它:

问题核心原因

首先看你的报错信息:

[Unhandled promise rejection: Error: Value [{"test":{"title":"test","subThings":[]}},{"test2":{"title":"test2","subThings":[]}}] of type org.json.JSONArray cannot be converted to JSONObject]

这个报错直接点出了关键:AsyncStorage里实际存储的是数组,但mergeItem方法只能处理JSON对象的合并——它会默认把存储值解析成对象,遇到数组自然就报错了。

再看你代码里的变量问题,这也是导致逻辑混乱的源头:

  • 第一个.then()里写了JSON.parse(decks),但decks这个变量根本没定义!这里应该是JSON.parse(things)(也就是AsyncStorage.getItem返回的存储值)。
  • 第一个.then()最后return { decks, subThings }里的decks同样是无中生有,应该改成return { storedThings: things, subThings }(换个变量名避免遮蔽外层的things)。
  • 外层定义的let things = {}完全没用,因为.then()里的参数things已经把它遮蔽了,后续代码里的JSON.parse(things)根本拿不到正确的存储值。
解决方案(适配现有数组存储结构)

既然你无法修改现有的数组存储结构,那咱们就放弃mergeItem,改用「获取数组→修改数组→重新存储」的流程,下面是修正后的代码:

const arrToObj = (array) => array.reduce((obj, item) => { 
  obj[Object.keys(item)[0]] = Object.values(item)[0] 
  return obj 
}, {}) 

export const addThingToThing = async (title, subThing) => { // 修正参数名,和内部使用的subThing统一
  try {
    // 1. 获取存储的原始数组数据
    const storedThingsStr = await AsyncStorage.getItem(THINGS_STORAGE_KEY);
    if (!storedThingsStr) {
      console.log("No existing things stored");
      return;
    }
    const storedThingsArray = JSON.parse(storedThingsStr);
    
    // 2. 遍历数组,找到对应title的项并更新subThings
    const updatedThingsArray = storedThingsArray.map(item => {
      const itemKey = Object.keys(item)[0];
      if (itemKey === title) {
        // 复制原对象,避免直接修改原数据
        return {
          [itemKey]: {
            ...item[itemKey],
            subThings: [...item[itemKey].subThings, subThing]
          }
        };
      }
      // 其他项保持不变
      return item;
    });
    
    // 3. 把修改后的数组重新存回AsyncStorage
    await AsyncStorage.setItem(THINGS_STORAGE_KEY, JSON.stringify(updatedThingsArray));
    console.log("Thing added successfully!");
  } catch (error) {
    console.log(`Error adding thing to thing: ${error.message}`);
  }
}

改动说明:

  1. 改用async/await的同步写法,避免.then()嵌套导致的变量遮蔽问题,代码逻辑更清晰。
  2. 直接操作存储的数组:遍历找到对应title的项,通过复制对象的方式更新subThings,避免修改原数组的副作用。
  3. 增加了空值判断,防止存储为空时的JSON解析错误。
  4. 修正了参数名不一致的问题(原代码函数参数是thing,但内部用的是subThing)。
关于打印对象但存储是数组的困惑

你打印的obj是自己把数组转成对象后的临时结果,但因为原代码逻辑错误,根本没正确读取到存储的数组,导致你看到的打印值和实际存储值不一致——修正后的代码会直接操作原始数组,就能解决这个认知偏差啦。

内容的提问来源于stack exchange,提问作者geoffjay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:06:47