Alright guys, it's time for yet another challenge. 1
And in this challenge you're going to be applying a lot of things, not just the things that you learnt 2
in the last lesson, but everything up until now. And the end result is going to be this beautiful to-do 3
list where you're going to be able to add some new items say buy milk click add and it gets added to 4
a list of bullet points. And effectively this is what you're aiming for. 5
But in order to achieve this, then you might want to refer to the index.js and look at the challenge 6
text. 7
So the first step is when text is written into this input, 8
the state should somehow be changed so that we can track the state of what's in the input. 9
Next when the Add button gets pressed, whatever is currently inside the input should be saved and added 10
to an array. 11
Now finally, the or the unordered list here, should display all of the array items as separate 12
list items. And all of these combined together 13
you should end up with this functionality. 14
Go ahead and fork 15
the starting project for this lesson. 16
Look around the app.js and the index.js to see what you've got to work with. And then pause 17
the video and try to complete the challenge. Once you're done, head back over here and I'll walk through 18
the solution with you. Have a go now. 19
All right. 20
So the first thing we're going to tackle is when new text is written into the input, it's state should 21
be saved. 22
So how can we do this? 23
Well we've done this quite a few times. 24
We are going to create a new constant in our app function and we'll give it a name that makes sense. 25
Let's call it the inputText and then maybe we'll have a function to set it called set 26
InputText. 27
And it doesn't matter what you've called yours as long as your code works it's fine. 28
And then we're going to of course invoke useState to be able to change and save the state of the input 29
text when it gets changed. 30
useState of course requires the import up here and then we get to define an initial value which I'll 31
set to just an empty string because the input is blank 32
to begin with. Now let's think about where we would want to use this input text. 33
Well in this, case we actually don't have an element onscreen where we're going to be able to see the 34
state changes for input text. 35
But what we should do though is to add a value property to our inputs and to tie it to this inputText 36
state. 37
So this way we are controlling the inputs and keeping the input value inline with the input text. 38
The next thing to do is, when do we actually want to change the input text, when do we want to call this 39
function? 40
Well it's probably going to be when this input gets changed. 41
So let's add an onChange to this input and get it to call a function which will call handleChange 42
and then let's add this function right here, handleChange, and then we get the event that's going to 43
be passed to it. 44
Now the next thing to do is to create a new constant which is going to keep hold of the new value of 45
the input. 46
So we'll just call it newValue 47
and I'm going to set it to event.target.value. 48
Now notice how in this case we've only got one input. 49
So we don't actually care about the name of the input, so we don't actually need to use destructuring 50
or anything fancy. 51
We just want to get a hold of the value of the target that triggered the event. 52
And once we've gotten that, then we can call setInputText and inside this function, we're going to 53
pass it this new value. And because in this case I'm not actually changing the inputText, 54
I'm not mutating it using setInputText, 55
I don't actually need the previous value. 56
It doesn't really matter. 57
I've got this whole new value that I want to give it which is going to correspond to whatever the user 58
is typing inside this input. 59
So now how can we confirm that this is actually working? 60
Well we can go ahead and pop it out and then use our Chrome developer tools to check the state of our 61
app. 62
So we've currently got one state being tracked and it starts out being equal to an empty string. 63
That sounds about right. 64
And as soon as I start typing, you'll see that the state updates to reflect the latest state. 65
So now that's being kept track of inside this input text. 66
So we've now achieved part 1. Part 2 involves tapping into the moment when the Add button is pressed 67
and then passing the current data in the input to an array. 68
So how can we do that? 69
Well the goal is to keep track of all of the items that the user has added inside an array. So we can create 70
a new constant which is going to hold an array of items. So we can call it items, todo items, whatever it 71
is you want to name it. 72
And then we're going to provide a name for the function which is going to set these items 73
and of course we're going to use state. 74
Now the initial value for items is just going to be an empty array. 75
It's not going to hold anything at all. And this means that when this todo list starts out we won't 76
actually see any bullet points. 77
So if we want to use this array of items to render all of the s to contain the text inside each 78
item, then we would probably have to use what we learned about the map function. So we can tap into our 79
items, call the map function and then inside the map function we can pass it an arrow function and inside 80
this arrow function we'll get access to each item or if you want to make sure that there's enough difference 81
between the array and the individual item, you call it todo item if you want. But effectively just be 82
sure that you know that this is going to be the singular form that comes from mapping through each of 83
the items. 84
And what we're going to return is an which has the to do item as the text in the list item. Now 85
notice how this syntax is not highlighting at all. It's not giving the different colors. 86
And the reason if I hover over it is it says unexpected token. It doesn't recognize this as code. 87
So if we highlight all of this and try to add the left hand curly brace, it'll add the curly braces around 88
this code and it'll get interpreted as Javascript. 89
Now we can of course simplify this down even more because we're only returning a single item so we can 90
get rid of the return keyword, 91
the opening curly brace, the closing semicolon and the closing curly brace to end up with just this. So 92
map through all of the items for each to-do item, create an and put the to-do item in that 93
is what we're telling our code to do. 94
Now all we have to do is call setItems when the Add button gets pressed. 95
Now the Add button is of course this one and we can simply add a onClick to it and get it to trigger 96
a function. 97
You can either get it to trigger an inline function so you could add simply some sort of arrow function 98
here. Alternatively and what I would prefer just in case we need to reuse this functionality, I'm going 99
to call a function code addItem. And then we get to create this addItem function up here and then inside 100
this function we're going to add whatever text is inside our inputs into our items array. Now 101
to do that, we of course have to call setItems. 102
So let's call setItems 103
and inside here we want to get hold of the previous items so that we can simply add the new input at 104
the end of the array as a new item. 105
So to do that, we're going to have to create a new arrow function. Inside the input of this arrow function 106
is going to be the previous items or previous values whatever it is you want to call it. 107
And then what we're going to return is going to be a new array using the spread operator, yeah 108
that's what you learned in the last lesson. 109
You can spread arrays, you can spread objects, you can spread butter. 110
It's really really handy. 111
So let's add our spread operator, add in all of the items from our previous items and then we're going 112
to add the new item which is going to be what's currently inside are inputText. 113
So I'm going to leave my code as it is now and I'm not going to simplify it further by removing the 114
return because I think this reads much better and it's already so short anyways. 115
So now let's go ahead and give our app a spin and see if it works. 116
Let's check our state. 117
We've got two. 118
One is holding a single value, 119
the other is holding an empty array. 120
Let's go ahead and start adding some text, Buy milk. That is being held inside of value which is the input 121
text. 122
And then when I click add, you can see that our array now has a new value. At index 0 123
it's got by milk. And because the array now has a value 124
the state of it has updated which triggered the map function to create a new list item. 125
If we decide to add another item say, buy egg, then our array also gets updated and we now have this beautiful 126
functionality. So the last thing that you might want to do is just to clear the input when you click 127
the Add button ready for the next item. 128
So the place to do that is probably going to be inside addItem so that once you've sent the input text 129
to the items array then after that has completed, you probably want to set the input text to an empty 130
string again. So we can call set input text and pass in an empty string just like that. Now whenever we 131
type in something, buy milk, hit add it gets added and then it gets cleared. Pretty neat right? Now 132
did you manage to complete this challenge? 133
If not, be sure to head back to review your code and once you're happy with how everything is done, then 134
head over to the next lesson and we're going to talk about how to manage a component tree and how to 135
pass state around in our component tree. 136
Notice how at the moment we've only got one app component and that's to try and keep it simple so you 137
can see what's going on because there's enough complex things going on. But in the next lesson we're 138
going to level up even more and we're going to divide up our app into separate components so that we 139
can pass state from child components up to parent components. As you can imagine 140
I'm going to need you to really understand everything that's already been covered so that you'll be 141
comfortable in the next lesson. 142
Take a breather, take a moment to pause, have a think, go for a walk, have some food and once you're ready 143
I'll see you on the next lesson.