DEV Community

Cover image for Spread Syntax ( ... )
Semir Teskeredzic
Semir Teskeredzic

Posted on

Spread Syntax ( ... )

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']
Enter fullscreen mode Exit fullscreen mode

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>
  );
} 
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

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)]
Enter fullscreen mode Exit fullscreen mode

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)]
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)