GraphQL报错Object not extensible:如何修改对象并替换数组元素?
解决GraphQL返回对象不可扩展的修改问题
完全可以搞定这个问题!我之前用GraphQL客户端处理返回数据时也碰到过一模一样的情况——这些返回的对象通常会被设置为**不可扩展(non-extensible)**甚至冻结,目的是防止意外修改原始缓存数据,但我们可以通过创建对象副本的方式绕开限制,再替换原数组里的对象。
具体操作步骤如下:
1. 定位目标专辑的索引
先找到你要修改的album在albums数组里的位置,比如通过专辑id来匹配:
// 替换成你识别目标专辑的条件,比如id、名称等 const targetAlbumIndex = albums.findIndex(album => album.id === "target-album-id");
2. 创建可修改的专辑副本并更新images
因为原album对象不可扩展,我们要创建一个新的可扩展对象,复制原对象的所有属性后再更新images数组:
if (targetAlbumIndex !== -1) { // 1. 用扩展运算符复制原专辑的所有属性,生成新对象 // 2. 同时复制原images数组,并直接添加新的图片ID const updatedAlbum = { ...albums[targetAlbumIndex], images: [...albums[targetAlbumIndex].images, "new-image-id-you-want-to-add"] }; // 用splice替换原数组中的旧对象 albums.splice(targetAlbumIndex, 1, updatedAlbum); }
为什么这个方法可行?
{...albums[targetAlbumIndex]}创建了一个全新的可扩展对象,摆脱了原对象不可扩展的限制;[...albums[targetAlbumIndex].images]复制出一个新的数组,让我们能自由添加新ID;- 你已经确认可以对albums数组执行push/删除操作,所以用
splice替换数组元素是完全合法的。
如果专辑结构更复杂怎么办?
如果你的album对象里有深层嵌套的对象(不只是简单的ID数组),可以用JSON.parse(JSON.stringify(album))做深拷贝,不过要注意这种方法会丢失函数、Symbol类型的属性:
const albumCopy = JSON.parse(JSON.stringify(albums[targetAlbumIndex])); albumCopy.images.push("new-image-id"); albums.splice(targetAlbumIndex, 1, albumCopy);
这样操作后,albums数组里就会变成包含更新后images的新对象,不会再碰到"object is not extensible"的报错啦!
内容的提问来源于stack exchange,提问作者Kevin Danikowski
相关产品推荐
相关产品推荐

