我正在从GraphQL后端提取数据.这是我正在收集的数据.

{
  "data": {
    "product": {
      "attributes": [
        {
          "id": "Capacity",
          "items": [
            {
              "id": "256GB",
              "displayValue": "256GB"
            },
            {
              "id": "512GB",
              "displayValue": "512GB"
            }
          ]
        },
        {
          "id": "With USB 3 ports",
          "items": [
            {
              "id": "Yes",
              "displayValue": "Yes"
            },
            {
              "id": "No",
              "displayValue": "No"
            }
          ]
        },
        {
          "id": "Touch ID in keyboard",
          "items": [
            {
              "id": "Yes",
              "displayValue": "Yes"
            },
            {
              "id": "No",
              "displayValue": "No"
            }
          ]
        }
      ]
    }
  }
}

然后迭代attributes数组并给出唯一的ID _id,以区分不同的items.事实证明,ID为With USB 3 portsTouch ID in keyboarditem的ID总是相同的.我使用的是nano 机器人.

以下是代码

import { PureComponent } from "react";
import { useParams } from 'react-router-dom';
import { Query } from '@apollo/client/react/components';
import GET_PRODUCT from "../../graphql/getProduct";
import { nanoid } from 'nanoid';
import ProductDetailComponent from "./ProductDetailComponent";
import './ProductDetail.css'


class ProductDetail extends PureComponent {
  render() {
    const { id } = this.props.params;
    const { currency, addToCart, closeCurrencyOverlay } = this.props;
    return (
      <Query
        key="yes"
        query={GET_PRODUCT}
        variables={{ id }}
        fetchPolicy="network-only"
      >
        {({ loading, data}) => {
          if (loading) return null;
          let newAttributes = [];
          data.product.attributes.map((attribute) => {
            attribute.items.map((item) => {
              item._id = nanoid(); // <-- Giving the id from here
            })
            newAttributes.push(attribute)
          })
          const newData = { ...data, attributes: newAttributes }
          return <ProductDetailComponent data={newData} currency={currency} addToCart={addToCart} closeCurrencyOverlay={closeCurrencyOverlay} id={id}/>
        }}
      </Query>
    )
  }

}

export default (props) => (
  <ProductDetail
    {...props}
    params={useParams()}
  />
);

我只是想知道为什么他们的身份证总是一样的.

Here is a screenshot of the Chrome dev tools Dev tools

推荐答案

如果您总是为items数组中的元素获取相同的id,并查看您的代码中赋值item._id = nanoid();的位置,这会让我认为这些对象共享相同的reference.

这里有一个简单的例子来说明为什么会发生这种情况:

// reference of array values
const yesNoArr = [
  { id: 1, text: 'Yes' }, 
  { id: 2, text: 'No' }
];

const objs = [
  // here both objects share the same reference of "items" property:
  { items: yesNoArr, text: 'with USB 3 ports' },
  { items: yesNoArr, text: 'Touch Id in keyboard' }
];

// if at this point you try to set _id to items[0]:

objs[0].items[0]._id = 123; // this will work fine and assign _id = 123
objs[1].items[0]._id = 456; // but this will overwrite previous "123" by "456" because they point to the same object

// result:
console.log(JSON.stringify(objs, null, 2));

如果要避免此行为,则必须制作items的修改副本,以便它们不会指向相同的引用对象. try 替换这段代码,看看它是如何运行的:

const newAttributes = data.product.attributes.map((attribute) => {
  return {
    ...attribute,
    items: attribute.items.map((item) => {
      // make a copy of each item to get a different reference:
      return {
        ...item,
        _id: nanoid(),
      };
    }),
  };
});

console.log(newAttributes);

Javascript相关问答推荐

ReactJS中的material UI自动完成类别

每次子路由重定向都会调用父加载器函数

基于变量切换隐藏文本

在vercel throws上部署带有gunjs的sveltekit应用无法找到模块./' lib/文本编码'

如何在angular中从JSON值添加动态路由保护?

配置WebAssembly/Emscripten本地生成问题

setcallback是什么时候放到macrotask队列上的?

JS—删除对象数组中对象的子对象

如何避免页面第一次加载时由于CSS样式通过JavaScript更改而出现闪烁

rxjs插入延迟数据

覆盖TypeScrip中的Lit-Element子类的属性类型

无法设置RazorPay订阅API项目价格

在JS/TS中将复杂图形转换为数组或其他数据 struct

顶点图使用组标签更新列之间的条宽

JavaScript -复制到剪贴板在Windows计算机上无效

如何让SVG图标在被点击和访问后改变 colored颜色 ,并在被访问后取消点击时恢复到原来的 colored颜色 ?

Promise.race()返回已解析的promise ,而不是第一个被拒绝的promise

如何在css中裁剪成一定Angular 的圆的一部分,而不需要复杂的多边形

与find()方法一起使用时,Mongoose中的$or运算符没有提供所有必需的数据

try 导入material 时出现错误NG0203