Android端调用undoNote函数报Malformed calls from JS错误如何解决
报错原因
调用undoNote函数时抛出Error: Exception in HostFunction: Malformed calls from JS: field sizes are different错误,是React Native JS侧与原生模块通信时参数格式不匹配导致的,核心触发点有1个直接原因、1个冗余逻辑问题:
- 直接原因:
AsyncStorage.setItem是桥接原生的异步方法,参数签名为setItem(key: string, value: string, callback?: (error?: Error) => void),要求前两个参数必须是字符串类型,分别为存储键名、待存储的字符串化内容,第三个可选参数才是操作完成的回调函数。你的代码中第二次调用AsyncStorage.setItem时,把回调函数错传到了第二个参数(值的位置),不符合原生侧的参数预期,JS桥在序列化通信参数时结构和原生侧接收的字段长度不匹配,直接触发该报错。 - 冗余逻辑问题:你在调用
AsyncStorage.setItem存储笔记前已经执行了props.setNotes(array)更新状态,在存储成功的then回调中又传入同一个数组重复调用setNotes,会触发不必要的组件重渲染,无实际意义。
修复方法
修正AsyncStorage.setItem的参数传值,清理冗余状态更新,同时补充索引越界判断避免极端场景报错,修复后的完整代码如下:
function undoNote(index) { // 索引越界拦截,避免访问不存在的回收站项 if (index < 0 || index >= props.moveToBin.length) return; const restoreNote = props.moveToBin[index]; // 生成新的笔记列表、回收站列表 const updatedNotes = [restoreNote, ...props.notes]; const updatedBin = [...props.moveToBin]; updatedBin.splice(index, 1); // 同步更新内存状态 props.setNotes(updatedNotes); props.setMoveToBin(updatedBin); // 统一持久化数据到本地存储 Promise.all([ AsyncStorage.setItem('storedNotes', JSON.stringify(updatedNotes)), // 此处根据业务需求传值:如果要更新回收站存储内容就传入序列化后的新回收站数组,要清空回收站就传入空字符串'' AsyncStorage.setItem('deletedNotes', JSON.stringify(updatedBin)) ]).catch(error => console.log('笔记持久化失败:', error)); }
如果你的业务逻辑是撤销操作时要清空deletedNotes对应的存储内容,只需要把第二个setItem的第二个参数替换为空字符串''即可,绝对不能在值的位置传入函数、未序列化的对象这类非字符串类型的值。
内容的提问来源于stack exchange,提问作者Tuong-Khang
相关产品推荐
相关产品推荐

