Spreadin' Out
Tags: javascript, beginners, react
Published: 2019-08-20 00:22:26

What is the spread operator and why does it matter? This is a question that I thought about quite a bit as I started to get into React.

As I continue my JavaScript journey I want to take advantage of these blogs to not only learn more about different features of the language but hopefully to be helpful to others who are trying to make sense of this wacky and powerful language.

##What is the spread operator?

`MDN's definition can seem a bit confusing at first.` 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.

Here is a brief example of one use of the spread operator.
```javascript
let account = {
   username: '',
   password: ''
}

account = {...account, username: 'Foo'}
```

Alright, so what does this mean? In the above block we used the spread operator to maintain our previous account object but overwrite the username key's value. It might seem a bit forced in this example as we could have simply overwrote the username value of the account. However, the idea is that the spread operator 'spread' out the key-value pairs of the account object into our re-assignment of account.

```javascript
let account = { username: '', password: '' }
/*
If we are assigning key-value pairs when creating the account
object, the spread operator is 'spreading' out those key-value
pairs into distinct pairs rather than being wrapped in
the original account object.
*/
...account = username: '', password: ''
```

One way to conceptualize this may be to consider that the spread operator is dropping the brackets off of the account object so that we have access to its key-value pairs.

##Why does it matter?

The spread operator is very useful in React. When we are always updating our state, we want to make sure that we don't ever modify the state but use setState to redefine our state with a new object. The spread operator allows us to make a copy of our current state without actually modifying our current state.

This means that we can spread out our current state and modify only 1 portion. I have found this to be very useful when dealing with nested states.

```javascript
state = {
   user: {
      username: '',
      password: ''
   },
   isLoading: false
}

this.setState({user: {...this.state.user, username: 'Foo'}})
```

In the example above we are modifying the username like we did in the first example. However, we are dealing with a nested object and we don't want to modify the user's password. By using the spread operator we can modify the username and use the password from the initial declaration.

We can also use the spread operator for arrays to allow us to achieve a similar interaction to a concat action.

```javascript
state = {
   numbers: [1,2,3]
}

this.setState({numbers: [...this.state.numbers, 4]})

this.setState({numbers: this.state.numbers.concat(4)})
```

This is similar to the previous examples where we are spreading out an object to preserve the original state. However, here as we are dealing with an array rather than just an object, we can simply provide a value to be appended to the array. The second example, concat is also not a destructive action and therefore will not be improperly modifying our state. However, the concat method is more commonly used to merge two or more arrays. As a result, the spread operator is a bit better here as we know what values we are adding to our array.

There are plenty of non-destructive actions that we can use to update our state without modifying the original. However, the spread operator has been one that I have found myself using again and again. It's versatility as well as non-destructive qualities make it the most appealing way to handle updates to state where we cannot simply overwrite one value but have to preserve some other part of our state object.

##References

* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat