Okay.
So now we're going to take a look at component states.
And when I say state I'm really referring to a piece of memory for this component so that we can add
or remove products from our products list.
Specifically, we're going to take a look at just adding new products into this list.
We cannot do that with a hard coded array like this.
We need something extra.
Now in early versions of react, what we would have to do at this point is not use just a JavaScript
function.
Here, we would actually need a class to store states inside memory for a particular component.
But since about react 16.8, react introduced something called React Hooks, which allows us inside
a normal JavaScript function to hook into a part of react that does some clever stuff behind the scenes,
so that react can reserve a piece of memory where we can track updates to state inside a component,
and when that state is updated or something changes with that state, then the component itself can
rerender and provide the updated states to the view in the browser.
So let's take a look at how this works.
Now, we did have a bit of react states when we first created a template.
We had a counter and we saw that in action.
But we're going to do something similar for the products in this case.
So in order to use states then we create a or use a use state hook.
So we do this by providing a const open square brackets.
And we'll set this equal to use state which we get from react.
Now VS code is very good at automatically importing stuff nowadays.
And we can see that this import of use state has come in from react.
So that's what we need.
And this use state hook.
It returns a stateful value and a function to update it.
So the stateful value is going to be a list of products.
That's what we put in the first part inside the square brackets.
And the function to update it is the second part.
So we'll say set products.
So we've got the ability to get the products effectively using this and set them.
And we can also give our states an initial value as well.
And for the initial value of this state, I'm just going to copy the list of products and put it inside
the parentheses for the use state.
And let's remove what we have hardcoded above the function.
And let's also just remove the third one which is a duplicate of the second one.
So if we want to add something to this array of products then we need to use the set products function.
So let's create a helper function inside here I'm going to say const add product and say equals parentheses
equals.
And we're using an arrow function here I'll come back and explain the syntax of this.
And the idea of this is well there's two ways of creating functions really.
There's this approach the arrow function.
And we specify a const.
Give the function a name.
This part here with the parentheses.
The empty parentheses is any arguments we wish to pass to this function.
And then we use an arrow and open curly brackets for the body of this function.
Alternatively, we could also just use a normal function and say function add product.
And then just use parentheses and create a function.
This way both ways are going to achieve exactly the same thing.
My small preference, and it is a very small preference, is just to use arrow functions inside react
components.
Typically you may see me doing something slightly different later on.
I'm not 100% consistent on this and it really doesn't matter.
You can use normal functions if you want.
I'm going to go for arrow functions in the main.
So inside here then we're just going to use the set products.
And what do we put inside here.
Well since we're not going to take an argument let's just add a product inside here.
So with the set products then what we can do is and this isn't ideal.
I'll just show you this approach.
First of all, and then I'll show you a better approach.
But what we could do is use something called a spread operator, and we could pass in as the argument
the products that we already have inside state.
And then after the spread operator, then we could add our new products, and I could give this a name
and say product three and I could give it a price and let's just say 300.00.
And I'm getting a warning here because I've created this function but not used it anywhere.
Now, I said, this is not great what we're doing here, but it should still work.
And I'll come back and correct it with a slightly different approach soon.
So where do we use this then?
Well, we need a button of course.
So let's just below the unordered list.
We're just going to add a button.
We'll give it an onclick event.
And then we can use our add product method.
Now inside an onClick event it might be tempted to add parentheses here because that's typically how
we call a function.
But in this case, what we want to do is defer the execution of this function until the onClick event
has been.
Well, the button has actually been clicked.
If we provide the function in this way, and we are getting a warning about this, telling us that,
hey, this isn't good, it's because this is being executed as soon as this component is rendered and
we don't want that.
We could do this and add parentheses and add an arrow function to call it.
This is going to do the same thing.
It's going to defer it.
And if we were passing an argument to this add product function, that is how we would write the code
inside here.
But if we do not need to pass an argument to this function, then we can just say add product as it
is.
And then when the button is clicked, then that's going to call the add product method.
And it's going to add that new product to the list.
And because of the way the Usestate hook works, that product is going to be added to the state in memory.
And then we should see it inside our browser.
So let's go and take a look and we'll just refresh the page.
Please bear in mind what I said about the hot reload.
You may see errors and warnings like this in your Chrome dev tools.
If you've got them open whilst you're developing and writing code, please do always just refresh the
browser just to make sure the warnings go away.
And if they do then it's not a problem.
Now I forgot to give the button a label so I can barely see it on the screen there.
So let's just say add products as the label of the button, go back to the browser and if I click the
button, then what we see is the products being added and it keeps getting added added added.
Great.
So we have the ability to add products.
But I mentioned that this was not a good use of the use state hook in this way, because I've just used
the state here to give it the products.
But what we really want to do is get into the existing state inside this method.
We do have access to that, and the way that we access the previous state is before the square brackets
there I can specify an argument and this can be called whatever we want.
But just to be clear I'm going to call it previous state.
And then we pass this as an argument to the function that we're using inside set products.
So this gives us access to the previous state.
And instead of dot dot dot products I can specify previous state.
Now this spread operator is very useful.
And this effectively spreads each element of the array.
So instead of it being an array inside square brackets.
Now after we use the spread operator it's going to have product one, product two.
And then we're adding on product three inside these square brackets.
So it's just a quick one liner way of adding something to an array in the way that we're doing it here.
So what we should find is that the functionality doesn't change.
It should still stay the same.
If I just refresh the page again add product, add product, add product, then we can see that our
state is being updated happening inside memory and it's causing our component to rerender and displaying
the outputs from the event of adding the product on our browser page.
And that's the result we're looking for.
But let's further refine our use of the use state, because we've got a very hard coded product name
and a hard coded price.
So everything's product three and everything's priced at 300.
So instead of that, we could just make use of the previous state to make this a bit more dynamic.
And we could say the name we could concatenate and I'll say pref state dot length and say plus one.
And let's move the price down there.
And for the price instead of 300 here we could open parentheses and say pref state dot length.
To get the length of the array multiply it by 100 and then plus 100.
So effectively this is going to give us in terms of product three it should be 300 based on this calculation.
And product four is going to be 400, so on and so forth.
And if we go back and test again and let's just refresh the page and we add products, then not quite
the result we're looking for.
It looks like we've got the products being concatenated on with the one.
And that's just a case of missing parentheses here.
So if I just highlight all of the previous dates we don't want to concatenate one onto this.
We want this to be a calculation of the previous state length plus one.
And if I go back and I refresh the page again what we should have is product three, product four,
product five, etc..
So that's our first hook we're going to take a look at.
So we'll use it often in this training course.
And another hook that we need to take a look at is so that we can do something when our component is
mounted or when our component loads, then we want to introduce a side effect.
When that happens.
And the side effects that we want to happen is we go out to our API and we fetch the products.
So instead of using our own products, here we go and get them from our API.
And we're going to take a look at that next.