Home > Software design >  How , Why this spread operator works
How , Why this spread operator works

Time:01-28

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));

  • Related