首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新状态数组时对象中的React唯一键被覆盖

更新状态数组时对象中的React唯一键被覆盖
EN

Stack Overflow用户
提问于 2019-08-13 14:04:17
回答 6查看 526关注 0票数 2

我有一个向购物车添加商品的函数。当一个按钮被点击时,我试图为一个新的对象项生成一个唯一的键。我让new Date().getTime()根据点击频率做这件事。我在函数内部测试了console.log,它为每个新对象生成不同的unique_id编号。当我尝试将现有的对象状态数组与新的item对象组合在一起时,问题就开始了。所有现有的unique_id都会被覆盖到最新的unique_id。我还对状态数组使用了React useState钩子。React在某种程度上是相关的,因为不应该直接编辑状态数组,而是通过setter方法进行编辑。

我尝试了.push.concatArray.from、扩展运算符、循环和在函数内部和外部赋值变量的组合。我知道这是pass-by-referencepass-by-value的情况,因为那些数组方法只是浅层拷贝。

代码语言:javascript
复制
const [cart, setCart] = useState([])

const addItem = (item) => {
   let cartArr = cart
   item['unique_id'] = new Date().getTime()
   setCart([...cartArr, item])
}

期望值:

代码语言:javascript
复制
[
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696123},
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696256},
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696377}
]

但得到的是:

代码语言:javascript
复制
[
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696377},
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696377},
{id: 1, price: 10.11, title: "The Art Of War", unique_id: 1565675696377}
]
EN

回答 6

Stack Overflow用户

发布于 2019-08-13 14:51:45

您可以将数组和对象连接起来,而不是将值推入数组中,请参阅下面的代码以供参考

代码语言:javascript
复制
  const [cart, setCart] = useState([]);
  const addItem = item => {
    item["unique_id"] = new Date().getTime();
    setCart([...cart, item]);
  };

这是codesandbox demo

票数 2
EN

Stack Overflow用户

发布于 2019-08-13 14:33:45

正如我在评论中提到的,这取决于您调用addItem的频率。下面的代码片段显示,如果您连续调用addItem,则所有项都会获得相同的时间(几乎总是):

代码语言:javascript
复制
let cart = [];

const addItem = (item) => {
    let cartArr = cart;
    let currentTime = new Date().getTime();
    item['unique_id'] = currentTime;
    cartArr.push(item);
    cart = cartArr;
}
addItem({ price: 10 });
addItem({ price: 11 });
addItem({ price: 12 });
console.log(cart);

但是,在通过引入console.log添加一些延迟之后,时间戳是不同的(不能保证):

代码语言:javascript
复制
let cart = [];

const addItem = (item) => {
    let cartArr = cart;
    let currentTime = new Date().getTime();
    console.log('Price: ' + item.price);
    console.log('Current time: ' + currentTime);
    item['unique_id'] = currentTime;
    cartArr.push(item);
    cart = cartArr;
}
addItem({ price: 10 });
addItem({ price: 11 });
addItem({ price: 12 });
console.log(cart);

所以,在这里,我认为React状态与时间戳或数组操作无关。

票数 0
EN

Stack Overflow用户

发布于 2019-08-13 15:02:04

正如@fiveelements所说,由于Date.now()不是一种可靠的生成随机值的方法,因此您会遇到ids冲突。幸运的是,浏览器有一个生成随机值的新功能。您可以尝试将以下内容用于您的ids:

代码语言:javascript
复制
const id = window.crypto.getRandomValues(new Uint32Array(10))[0];
console.log(id);

您可以阅读有关window.crypto object on MDN的更多信息。包括IE11:https://caniuse.com/#search=crypto在内的所有现代浏览器都支持它。

如果您从数据库之类的地方获得数据,那么您可能已经有了某种可以使用的唯一id。如果可以在渲染之间保持key的一致性,则可以通过避免不必要的重新渲染来提高性能。但是,如果您没有任何id,这个代码片段可以帮助您动态生成它们。

您还可以检查此CodePen

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57471938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档