#javascript #json #reactjs #react-hooks
#javascript #json #reactjs #реагирует-хуки
Вопрос:
У меня проблема примерно на 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 обновляет все мои переменные, делает весь мой код плохим.
Спасибо, и я надеюсь, что вы найдете решение. (и извините, если есть какие-то ошибки, я французский)
Комментарии:
1.
shuffle
изменяет исходный массив.2. вызывается refrence, глубокое клонирование аргументов в функции shuffle,
tab = tab.slice()
Ответ №1:
JavaScript передает им объекты по ссылке, вот почему. Если вы хотите избежать этого, измените цикл for с помощью map
....
const toReturn = tab.map(item =>{
...
});
return toReturn
Комментарии:
1. Это не очень помогает, потому что алгоритм перемешивания изменится. Фишер-Йейтс должен делать это на месте.
Ответ №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
Комментарии:
1. Это неэффективно. Однако для этого не нужно глубокого клонирования
array.slice()
.