All right guys.
So in this lesson I want to talk about ways in which we can reduce the amount of code and simplify our
code here. And in large part, that's going to involve something called the Spread Operator.
So go ahead and get hold of the starting sandbox and fork your own copy.
Now to begin, I want to show you what the spread operator actually does.
I'm going to write my code inside the index.js.
So let's say that we had an array called citrus and it was equal to various citrus fruits such as Lime,
Lemon, and Orange.
And then I had another const called fruits which is going to be another array,
so let's say Apple, Banana, and Coconut.
And what if what I want to do is to be able to add all of the contents in the citrus array into my fruits
array at the end, so I can put the Lime into theCcoconut and shake it all up?
Well in this case, what I could do is I could individually go through this array and push each of those
items to my fruits array,
but there's a much much easier way of doing this.
I can simply use the ES6 spread operator which basically is just three full stops like this (...),
and then I can add the name of the array that I want to expand into this position,
so in my case it's citrus. And so now if I go ahead and log the value of my fruits array, then you'll
see that it's equal to Apple, Banana, Coconut,
so the original array that I've typed out manually, and then it's got all of the rest of the items that
came from the citrus array. And what it did is it took this citrus array, expanded it, or spread it into
individual items and added each of those items into this position where I specified ...citrus.
Now you can of course change the position, so if you wanted Apple to be the first item and then you
wanted to insert the citrus array, then you can do it like this.
And now when it gets printed you can see Lime, Lemon, and Orange now goes after Apple and before Banana.
Now you can use the spread operator with objects as well.
For example, if I had a const called fullName and it was set to equal to a fName being James,
lName is, Bond, and then I created another object called user, and I wanted to be able to insert the
fullName object into my user object, then I could simply do ... and then the name of the object
I want to insert and then any other items that I want.
So maybe I'd have an id and maybe I'd have a username of, "jamesbond007" and now this user object
is going to be comprised of all of the elements inside the fullName object as well as any other ones,
that I've misspelt, such as the id and username.
So let's go ahead and log the user object and you can see that this object has fName, lName, id, and
username.
Now notice how this is not the same as if we simply just inserted this object fullName into this user
object.
What happens in this case is when we log the user object, you can see that we get a new object being
nested inside our user object.
And now we've got something with a key, a fullName, and a value of this object.
This is not what we want,
instead, what we wanted was to spread all of the items inside the fullName object into our user object,
and so they all end up in the same object, like so. Now if this reminds you of maybe a pain point that
we had in our previous app, then you are spot on.
This is exactly what we're going to use to be able to simplify the code that we've got inside our handleChange(),
which at the moment even though it looks very clear, it's a bit too long for what it's trying
to achieve.
What can we do here instead?
Well instead of having all of these if-statements, we can simply delete all of it, and then we can return
an object where we use the spread operator to add in the previous value of the object, so be it the
lName property, or the fName property, or the email property, whatever it is that we had previously,
and then we're going to add in a new value for whichever name of input that got passed in, and the value
that the user typed in. At this point
you might think this code would just work as it is, but if we actually tried to run this and open up
my console so I can see my state hooks, notice how if I start writing First Name, nothing actually happens.
But it seems like something is being added with a key of name.
What's going on here?
Well, it's literally interpreting this as the fact that you want to create a new key-value pair where
the key is the word name. And instead, this part is actually saying is declared but it's never read.
So we're not actually able to tap into this right here.
Now you might think that the solution is maybe we'll just get straight to the point. We will say event
.target.name. And despite my warnings about never using the event inside a set state, you'll notice
that this doesn't even work.
So whatever it is that we're typing here, it's being interpreted as a string instead of the value of
a particular variable or property.
What we have to do instead, is we need to add the value that we want inside and an array syntax.
And notice how as soon as I do that, then almost magically everything starts working exactly the way
that it's supposed to.
But what's actually happening behind the scenes?
Well, notice there's a lot of people who are wondering the same thing,
and the best place to find all the other wandering souls is of course Stack Overflow.
So in this case this guy has a key which is a variable and it holds a string value,
he wants to use that string as the key when he creates a new object. But it doesn't seem to work because
it's just taking the word key instead of the actual value that's stored inside key,
so exactly the same thing that we're experiencing. And down here you'll notice a highly upvoted answer
telling you how you might do this before ES6.
Well, you could create a new object and then use this array syntax to be able to set it as the key
of the object.
But luckily for us because we're using Babel, because we're using React, and because we are now no longer
in before 2018, we can simply just use this new feature where we add a set of square brackets in front
and then put our key variable inside to get the actual value of the variable rather than for JavaScript
to just interprete it as a literal string.
So I'm going to link to the Stack Overflow question and if you're curious then have a read about it.
But essentially, this is going to be the syntax that you're going to get used to.
We've got the name that comes from our event.target .name,
and we're simply adding a set of square brackets in order to get hold of the value of this variable,
rather than using it like what we did here
when we create object laterals where we just add a string as the key.
So if you wanted to, you could in fact shorten this code even further.
For one, we could get rid of this return, right? Because we only have one thing being returned in here
which is this single object, we could actually get rid of this outer curly brace,
this corresponding closing brace, this semicolon and only end up with this object, like so. But of course
JavaScript gets confused because it thinks that this is the body of your function,
so instead we have to wrap it inside a set of parentheses to tell it,
"Nope this is actually an object and we're just using very very terse syntax to try and achieve this."
Now, even though this is very, very short, we're now down to two lines.
I don't actually really like this syntax because it's kind of confusing as to what's going on.
There's so many curly braces, so many of these parentheses, it's a bit confusing.
So I think simplifying code is great when it keeps its meaning.
So what I would prefer is to keep it like so, where we have a function that we're passing over to setContact
,
it gets hold of the previous value and returns a JavaScript object that includes all of the items from
the previous JavaScript object, the previous value, and then adding on the new key-value pair, with the
key being the name of the event.target and the value being the new value that's been typed in. This
even as it is, is going to take some getting used to.
So have a play around with the code
and once you ready, head over to the next lesson where I've got a challenge for you to try and solidify
this even more.