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

React中使用Apollo获取API数据后排序报错求助

问题解决:Apollo数据排序时报错“TypeError: Attempting to change configurable attribute of unconfigurable property”

问题原因

Apollo Client返回的data对象(包含内部的ammo数组)是被冻结/设为不可配置的,这是Apollo为了防止意外修改缓存数据做的限制。而sort()是原地排序方法,会直接修改原数组,这就触发了不可配置属性的修改限制,导致报错。

解决方案

不要直接修改Apollo返回的原数组,先创建数组副本,再对副本排序:

修改后的完整代码

import { useQuery, gql } from '@apollo/client';
import AmmoBox from "./components/Ammo"
import {Grid} from "@chakra-ui/react"

export const GET_AMMO = gql
`{
    ammo{
        item {
            id
            name
            shortName
        }
        damage
        penetrationPower
        caliber
    }
}`

function App() {

  const { loading, error, data } = useQuery(GET_AMMO);

  if (loading) return 'Loading';
  if (error) return 'Error';

  console.log(data.ammo);

  // 创建数组副本后再排序,避免修改原数据
  const sortedAmmo = [...data.ammo].sort((a, b) => a.damage - b.damage);

  return (
    <Grid templateColumns='repeat(5, 1fr)' gap={6}>
      {sortedAmmo
      .map((ammos) => (
        <AmmoBox name={ammos.item.name} caliber={ammos.caliber} penetration={ammos.penetrationPower} damage={ammos.damage}/>))}
    </Grid>
  );
}

export default App;

可选的副本创建方式

除了展开运算符[...],也可以用slice()方法实现数组浅拷贝:

const sortedAmmo = data.ammo.slice().sort((a, b) => a.damage - b.damage);

两种方式生成的新数组都是可修改的,不会触发Apollo的数据保护限制,同时能实现按damage字段排序的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:50:33