【问题标题】:React variable change but it shouldn't反应变量变化,但它不应该
【发布时间】:2021-05-19 22:16:47
【问题描述】:

我有一个问题大约 3 个小时,我不明白为什么,

下面的代码应该可以解释我的问题:

import {useEffect} from 'react'

function shuffle(tab) {
  console.table(tab) //shows initialdata
  var i, j, tmp;
  for (i = tab.length - 1; i > 0; i--) {
      j = Math.floor(Math.random() * (i + 1));
      tmp = tab[i];
      tab[i] = tab[j];
      tab[j] = tmp;
  }
  return tab;
}

function App() {

  useEffect(() => {
    const initaldata = [{a:1}, {a:2}, {a:3}, {a:5}]
    console.table(initaldata) //shows initialdata
    const finaldata = initaldata 
    console.table(shuffle(finaldata)) //shows initialdata shuffled
    console.table(initaldata) //shows initialdata shuffled,  why ?

  }, [])
  return null;
}

我在一个函数中尝试了多种解决方案,例如孤立的“shuffle(initialdata)”。

shuffle 函数更新我的所有变量这一事实使我的所有代码都无法正常工作。

谢谢你,我希望你能找到解决办法。 (如果有错误请见谅,我是法语)

【问题讨论】:

  • shuffle 改变原始数组。
  • 引用调用,深度克隆shuffle函数中的args,tab = tab.slice()

标签: javascript json reactjs react-hooks


【解决方案1】:

JavaScript 通过引用传递对象,这就是原因。如果您想避免这种情况,请使用地图更改 for 循环

....
const toReturn = tab.map(item =>{
...
});

return toReturn

【讨论】:

  • 这没有多大帮助,因为洗牌算法会改变。 Fisher-Yates 的重点是就地执行。
【解决方案2】:

Javascript 通过引用传递对象,包括数组。这意味着当你这样做时

const finaldata = initaldata 

finaldata 和 initaldata 仍然指向内存中的同一个数组。如果您不想修改原始数据,则需要在修改之前对数组进行浅拷贝或深拷贝。

【讨论】:

    【解决方案3】:

    您可以在运行 shuffle 之前尝试像这样复制数组 =>

    const finalData = JSON.parse(JSON.stringify(initialData));
    console.table(initialData);
    

    希望这能有所帮助 https://dev.to/samanthaming/how-to-deep-clone-an-array-in-javascript-3cig

    【讨论】:

    • 这是低效的。不过不需要深度克隆,array.slice() 应该这样做。
    猜你喜欢
    • 1970-01-01
    • 2015-06-25
    • 2022-07-29
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多