为啥 Apollo/GraphQL 返回一个不可扩展的对象?

Posted

技术标签:

【中文标题】为啥 Apollo/GraphQL 返回一个不可扩展的对象?【英文标题】:Why does Apollo/GraphQL return a non extensible object?为什么 Apollo/GraphQL 返回一个不可扩展的对象? 【发布时间】:2017-12-20 17:27:26 【问题描述】:

我正在使用 VueJS 构建一个应用程序,并且我正在使用 Apollo 客户端通过 GrapgQL 服务器从数据库中获取数据。我的代码如下所示:

    apollo.query(
        query,
        variables
    )
    // context.commit('populateComments', payload) triggers the mutation
    .then(payload => context.commit('populateComments', payload))

然后,在我的突变中,我有以下内容

    populateComments: (state, payload) =>  
        state.comments = payload.data.comments
    

当我尝试在另一个突变中将另一个对象推入 cmets 数组时,我收到一条错误消息,显示“无法添加属性 300,对象不可扩展”。我发现以下工作

state.comments = Array.from(payload.data.comments)

但是.. 我不确定像这样重复复制大型数组的效果如何?这是首选的方法吗?

【问题讨论】:

【参考方案1】:

我自己没有使用过 GraphQL/Apollo,但我想它会坚持不改变数据的原则,因此对象不可扩展。您可以在突变中做的是将数据分配给这样的状态:

Vue.set(state, 'comments', payload.data.comments)

这将确保对象最初被深度复制,然后以 Vue 友好的方式更新,以支持反应性。你可以阅读更多here。

【讨论】:

【参考方案2】:

我也遇到过同样的问题。

我最终做的是在将数据发送到 Vue 提交之前执行 _.cloneDeep。

【讨论】:

【参考方案3】:

像你和 Max 一样,我也遇到过同样的问题,对我来说唯一的解决方案是在之前克隆对象

如果您使用 Lodash (https://lodash.com/docs/4.17.5#cloneDeep):

const commentsClone = _.cloneDeep(payload.data.comments)

如果不是(https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Object/assign):

const commentsClone = Object.assign(, payload.data.comments); 

【讨论】:

Object.assign 会给你同样的问题,你的对象/类型是深度嵌套的【参考方案4】:

这应该可行:

const commentsClone = [...payload.data.comments];

【讨论】:

以上是关于为啥 Apollo/GraphQL 返回一个不可扩展的对象?的主要内容,如果未能解决你的问题,请参考以下文章

Apollo GraphQL“不能为不可为空的字段 Mutation.createUser 返回 null”

为啥 GraphQL 查询返回 null?

为啥 GraphQL 查询返回 null?

为啥 GraphQL 查询返回 null?

为啥 GraphQL 查询返回 null?

TypeScript,Apollo GraphQL 产生不可分配的节点获取错误