here's the code
funtion App(){
const [Cards, setCards] = useState([
{id: 0 , name: 'Harry Potter'},
{id: 1 , name: 'Hermonie Granger'},
{id: 2 , name: 'Ron Weasly'},])
const shuffle = (arr)=>{
// just shuffle the arr then return it.
}
return (
<div className="App">
<div>{Cards[0].name}</div>
<button onClick={() => {
setCards([...shuffle(Cards)])
console.log(Cards)
}}>Testing</button>
</div>
);
}
why did this works setCards([...shuffle(Cards)])
and not this setCards(shuffle(Cards))
.
Even if i dont use the spread operator it shuffles the cards (see in console) but not displaying it in the page.
:) ;) ....
CodePudding user response:
JavaScript is a language that passes objects by reference. What that means is that objects will always equals to itself even if it's internal values have changed. To demonstrate this, take the following snippet:
const a = [1, 2, 3];
const b = a.sort((x, y) => y - x);
console.log('a:', a);
console.log('b:', b);
console.log('equals:', Object.is(a, b));
In the above snippet, you will see a
and b
contains the same values even though only b
is reordered by .sort
. You will also see a === b
equals true
. This is because Array.prototype.sort
performs in-place sort. From the documentation:
The
sort()
method sorts the elements of an array in place and returns the reference to the same array, now sorted.
And from React's useState
documentation:
React will ignore your update if the next state is equal to the previous state, as determined by an Object.is comparison.
So, to answer your question to why spread operator fixes it, no, the spread operator does not actually fix it.
The actual fix is that new array that you create while using [...array]
, because a new array is a new reference:
const a = [1, 2, 3];
const b = [...a].sort((x, y) => y - x);
console.log('a:', a);
console.log('b:', b);
console.log('equals:', Object.is(a, b));