Spread Syntax ( ... )
Tags: javascript, react
Published: 2021-08-06 09:33:46

MDN Web docs state following for the spread syntax:

> Spread syntax (...) allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

##Spreading the arrays

In day to day coding we are mostly using spread syntax to copy the array or the object to the new array. For example:
```
let companies = ['Nestle', 'Volvo', 'Klarna'];
let newCompany = 'Adobe';
companies = [ ...companies, newCompany];
// This returns ['Nestle', 'Volvo', 'Klarna', 'Adobe']
```
So basically we use spread syntax when we want to include all elements from either array or object to some kind of list. 

##Use case with ReactJS

This comes handy in handling state in React when you want to have previous state and include a new piece of data like so:
```
import React, {useState} from 'react'

export default function App() {

    const [colors, setColors] = useState(['Red','Green','Blue']);
  
    const changeColor = (colorName) => {
     setColors((prevState) => [...prevState, colorName])
    }

  return (
    <div className="App">
      <h1>Colors</h1>
      {colors.map((color) => <p>{color}</p>)}
`     <button onClick={() => changeColor('Gold')}>Gold</button>
    </div>
  );
} 
```
Here we initialise the state with primary colours `Red, Green, and Blue`. Then we use `prevState` and spreading it inside a new state so we can get all the elements in the previous state and add a new element.
We just hardcoded `Gold` here but we could make a dropdown or input field to add whatever we like.

##Spreading multidimensional arrays

When we are not copying multidimensional arrays, we indeed create a copy:
```
let first = [1, 2, 3, 4]
let second = [...first]

console.log('First', first)
// First (4) [1, 2, 3, 4]
console.log('Second', second)
// Second (4) [1, 2, 3, 4]
```
Now if we remove the element from the `second` array, the change will happen only in the second array.
```
let first = [1, 2, 3, 4]
let second = [...first]

second.shift()

console.log('First', first)
// First (4) [1, 2, 3, 4]
console.log('Second', second)
// Second (3) [2, 3, 4]
```
This is because the `second` array is an actual copy in the memory. However, when we deal with multidimensional arrays we get a red note from MDN docs:

>Note: Spread syntax effectively goes one level deep while copying an array. Therefore, it may be unsuitable for copying multidimensional arrays, as the following example shows. (The same is true with Object.assign() and spread syntax.)

So when we have a multidimensional array we don't get a copy but a reference, therefore changing data in the "copied" array will affect the original.
```
let first = [[1], [2], [3], [4]]
let second = [...first]

console.log('First', first)
// First(4) [Array(1), Array(1), Array(1), Array(1)]
console.log('Second', second)
// Second(4) [Array(1), Array(1), Array(1), Array(1)]
```
So far it is behaving as expected, but when we change one of the elements, we also get the change in the original array:
```
let first = [[1], [2], [3], [4]]
let second = [...first]

second.shift().shift()

console.log('First', first)
// First(4) [Array(0), Array(1), Array(1), Array(1)]
console.log('Second', second)
// Second(3) [Array(1), Array(1), Array(1)]
```
This is one of the things one has to keep in mind if the multidimensional arrays are spread and therefore referenced.

Thank you for reading.