Lesson 18
Introduction to React.js [raw] - Software School (2024-04-17)
Video Transcript
Okay, like I said, we do a to-do list today as an exercise for this introduction to React.js,
a library that we use to build drawn-end user interfaces. Here's the wireframe.
Again, just a simple text box, we can type something to do, click Add, and then a bullet
point list in the bottom here. So, let's get to it. So, in your code sandbox environment,
if you go to code sandbox.io, the link I posted in the Zoom chat, slash s slash react dash new,
I should have this environment here after you fork in the top right. There's a directory called
SRC, and then slash app.js. We're interested only in this one. So, what happens here,
we have the code in the middle, and then the right-hand side is the manifestation of this
code. It's like a mini web browser within the whole browser here. So, you can refresh and do
things. So, as we change the code here, for example, I say 123 to this, it will appear here.
Okay. So, the way everything's set up here, React is pretty simple. So, we have a public
slash index dot html page, and this page in the body, there's a div element whose
ID attribute is root. So, the whole React application is injected here.
How does it work to inject? Well, the file src slash index, we have some document get
element by ID root, meaning it's going to find that element, and then finally,
it's going to render the React application at that element. This is not necessarily,
you don't have to understand this, what's going on right now, but that's how the mechanism works
to inject the React application. Now, going back to src slash app.js, let's get going,
doing this to-do list. So, let's start off with just have these text box, right? How can we build
that? So, in React, we build things with components. So, a component in its most basic form is just a
function, and you give it a name. For example, this is the app component. Now, the component has
to return something, and that's the view. That's what we're going to see. So, you return for this
function, something that looks like html, but it's actually what's called jsx. Basically,
a synthetic sugar for a function called in JavaScript, and the function is react dot create
element. But writing the code with react dot create element is just too hard to see. So,
we prefer writing it the declarative way, synthetic sugar with jsx. It looks just like html. Pretty
much html written within JavaScript code. And then you can just write this right here, and it will
appear here in the browser. Just like that. So, if you do any change like I did here, let me remove
d123, it will appear on the right hand side as so. Okay, let's just remove everything and just have
a div there. So, let's set started. What's the element we're going to use to make a text box?
Well, it's going to be the input, just like html, right? So, in html world, we have the input element
with this input tag, right? Now, in the react world, it's the same thing except we use different
terminology. When you say element in html world, in react world, we say component. When we say
attribute, like the type attribute of the input type text, in react world, that's called a prop,
which is short for property. So, let's do this here. Now, react requires you, when you have a
self-closing tag, to add a slash before the greater than. Otherwise, it doesn't work. You know, in
html 5, you don't need to add a slash, but in react, we have to do a slash there. Now, you can see
there's a text box there. Now, let's add the button to add the to do. I'm just going to break a new
line add button, type button, and I'm going to say add, and then close that. So, in this case,
we have a button component with the type prop set to button. Now, what's between the open and close
tag? In react world, we call this the children prop. It's a special kind of prop that you can place
instead of placing here. You can place it between the open and closing tags.
Okay. Now, let's make this style a little better. I think I want to the input to take over the whole
line and add some padding to the button. So, let's add a container here. And this container div
will contain the input and the button. And then we add a class. Now, to add a class in react world,
you have to be careful. You should use class name instead of class. In html, we have the class
attribute. But in react, we have class name. Why is that? Well, because react originally,
we used to write components using class keyword. You know, object-oriented programming.
So, it's more encouraged to use just functions now. But the reason we don't use class here,
and instead use class name is because class is a keyword in the JavaScript language that's used to
create a blueprint for objects. Anyway, let's call this the
to do input container about that. So, we got this class. Now, where do we set the styles?
Well, the styles will be in the file styles.css here. But notice there's an import at the top
for dot slash, which means current directory, the file styles.css. So, when this is done,
it will import the styles from this CSS. So, I can just go here and say
the class name that I did here. So, I'm just going to copy that. Make sure there's a dot before
because it's a class. So, I just want to make the text input kind of expand and push the button
all the way to the right. To do that, I can set this container to be display flex
like this. I can press Ctrl S in my case, Windows to save this. Enough is going to
happen yet because I got to set the flex number for this input. So, I'm going to add a class to
that input. So, class name, remember, you have to have name. And this is going to be, let's say,
to do input, just like that. Now, I'm going to go back to styles.css, dot to do input. I want this
to have flex property, colon one, so that it will expand and push everything next to it
all the way to the end of the line. Okay, if you want to add more stuff to make this prettier,
you're free to do so. Maybe add some padding, like eight pixels, like that. Maybe you can
change other stuff. That seems okay to me as it is. Now, for that button add, I want to add
some padding to the left and right to make it, you know, occupy more space. So, let me say
add button class here. And I want to add some padding to top and then to left and right.
Top bottom, I want to be maybe eight. And then space 16 pixels for left and right. Now, I need to
add this class, apply that to the button. So, I'm going to say class name there, line eight,
add button. And there's some space now to the left, to the right, and then some in the top
bottom. Although I kind of stretch the input, so it might not have any effect.
In any case, it looks good to me. Now, let's do the follow me. So, we want to have the to-do list
right after that, right? We have to have here the wireframe again. So, we just added the text,
input the add button. Now, we have some bullet points for each to do. Well, that's easy. You
could just do a UL, right, unordered list with some allies. But, well, that's going to be dynamic
because we want to click add and keep adding stuff. But, for now, could just fake some stuff.
So, we have kind of a placeholder there. So, right here, I'm going to add a UL.
And I don't have anything yet, so just clear some fake to-dos here. Maybe just like what we had.
Do the laundry, walk the dog. Do the laundry, the first ally. And then the second ally is walk the dog.
Okay. Maybe you can increase the font size. I don't know if you can see. Let me know if it's
a small. Let me add a class of the UL to-do list. And I'll add some font size there to make it bigger
for you. That's to-do list. Back in styles.css. And I'll increase font size maybe. Let's see if it's 16.
24, about that. There you go. You can change it to whatever you want, okay? I just changed it so
it's easier for you. All right. How's everybody doing so far? Any questions? You were able to get
this far without an issue? All right. So, keep going.
All right. We will leave this added and removed for later. Let's just focus on a basic functionality.
That is, we want to type something to the box and click to add to the bullet point. Now,
that's going to take some thinking. So first, let me just, well, let me just start the easy way.
That's just for the add button. We've got to separate every kind of thing, task we have to do
here because there's too many things going on. So I want to focus just on the add button
because it might be easier to start off that way. And later we will introduce the concept of state
to control the input, whatever the user types. So focus on add. So I want to add some initial value
to this input just for development. We can remove it later. So I'm going to add a value
prop. Remember React World, we call it prop, not attribute. And let's just have some place
sort of like we had, wash the dishes. So you can see the initial value for the input is wash the
dishes just for now so we can develop have something already written there. Okay. Now,
let's focus on add. When I click add, I want the text that was typed in this input to be added to
this list. Now let's focus add is when I click it's an event on click. So I got to go to the button
add a prop called on click and define its value like this. Now HTML, you can do this but the on
click is all lowercase. But react world it has to be camel case. Okay. So after on make sure the
CS capitalize. Now the syntax for JSX is the equal sign followed by curly braces. It's not the
quotes. Actually, I put quotes for the other ones because when you have string value for a prop,
you can kind of drop the curly braces. So that's actually curly brace there but I can drop it
because it's optional. Okay, but always think there is a curly brace there. That's why I have to add
it here. Now this has to be a function in the HTML vanilla. It would be just a string with the name
of the function and parentheses. But in react world, you got to give just the name of the function,
no parentheses. So we're going to say on add click. That's the name I'm going to give to this
function. Again, you're free to use whatever name you want. I think it's descriptive to use on add
click. Now we got to define this function somewhere. And we're going to do it right before the return
value. I'm going to break two lines there. Make sure is within the function. Okay. Not outside.
So I'm going to create a function on add click here parentheses.
Like that. Now when you click, you know, events in HTML JavaScript, there's always an event
parameter there. But I don't think I care about it right now. So I could have just omitted or you
don't just don't have to use it. But anyway, so when I click add, this function is going to be called.
So I want to first access this value here. How can we do that? Now that's the problem in vanilla
HTML, what we would do is, okay, I'm going to get this input in some sort of way, like I can use
query selector, I can use get element by ID provided there's an ID attribute added to the input,
and so on. But react world, we don't do that. We want to avoid doing that. Please don't do that.
React world, we got to first do the following. We got to make a variable that will hold the
value that the user types. And then we're going to control this input so that react will know
every time you type anything react will Oh, see, hey, you type something, therefore I will react
to it. And I will update the variable value. And then because the value updated, react will know,
hey, something was changed in what we call state. So when the state changes, react will
re render the component. In this case, it will call the function app again. And since the value
for what the new thing we typed will be there, it will call it here in the input with that value.
Now enough talk, let's just get to it. So first, I have to go to the input here.
And this value, I'm going to take it out. I'm going to create a variable for that. Now let's call
this, I don't know, to do text about that. Now this variable got to go here outside. Now I can't
just do to do text like this. Because react will not know that you're going to change this. The only
way we can know how to change something changed as if it tracks it by placing the variable in the
state. This value has to be placed in the state so react can track its value with time. So to do
that, we have to call what's called react dot use state hook, H O O K. Now, in order to use that,
you're going to see there's an our react is not defined. So we got to go here in the top
and say import the react from react. So this means okay, we're importing the react object
from this library react that was installed with MPM, the node package manager, for example,
or you could use your in any case. When I call react dot use state, I'm telling react, hey,
I want to keep track of a certain value. And here's the initial value that I pass as the argument.
Now this thing is going to return an array. And it has two things. First is a variable that you
can access the value here. In this case, you could access wash the dishes, let me put in a new line.
It would be like this. And then the second value is like a function
that we can do use to change this value here. Instead of wash the dishes, maybe I want to reset
and clear everything and set it to an empty string after I add. Okay. Now, because of this,
what people typically do is they destructure this array, meaning they extract the first element of
the array into a variable. And then they extract the second element, which is a function into another
variable, instead of them having to say to do tax sub one to access the first element and to do
tax sub one, zero one to access the second element. Okay, so people like doing this notation with the
square brackets, and then you extract each like this. So this is taking, okay, we have an array
on the right hand side. I want to take the first element and set the variable to do tax with that.
I want to take the second element and set the variable set to do tax with that. Now, because
I know the second variable here is going to be a function, I usually always call it set whatever
the name I use for the variable, all in camel case. This is just a naming convention that
everybody uses to, you know, just keep things consistent. Okay, and after that, you can see
wash the dishes there without an issue. And but if I click and try to type anything at all,
nothing works. And that's because the value of to do tax is always fixed. There's no way
of changing it. In order to do that, we've got to add a prop to the input that's called own change.
And then you got to do the same approach. Okay, let's add a function here. Let me call
on to do tax change. And then I'm going to go outside here. Make sure it's either after the
ad click or before it doesn't matter, but has to be within the app function. So let me call it function
on to do tax change. By the way, let me enable wrapping here. So you can see this better.
Editor word wrap. I want to enable word wrap so we don't have to scroll horizontally. There you go.
And I can see on change. Now this function we just defined here, you can do add event
like that. Now, we're going to use event now because when you type something there,
for every character that's typed, it's going to call on to do tax change. And you can access
the text by saying event dot target dot value. Well, target is actually the input element.
And the input elements has a value, remember? And that's how we access what was typed there.
Then we can take this and call set to do text with that value. That's the new thing that was just
typed. That way, if I go there and try to type it, it's working now. If I refresh, what's going on
now? Well, when I type the letter a, it's going to go here. Okay, you typed a, I'm going to call the
own change prop of the input, which is on to do tax change. Then I'm going to call the function set
to do text, which is used to change the state of the to do text. And then we're going to take
whatever was typed under event, the targeted value and replace that. And then the moment we change
the value of to do text, that means it's a state change, react when it sees a state change,
we'll react to it. Hey, state has changed. Therefore, I must re render. So it calls up again, and
returns a new view. Now in this new view, we'll contain to do text with its new value. Therefore,
we see the wash the dishes with the a at the end there. And that's how the mechanism works.
Very important principle in react that you have to understand every time the state changes,
a re render occurs, the component will be re rendered.
I've already doing so far any questions.
All right. So let's keep going.
Great. But so far we don't have anything to add. So let's go back to the add button.
Remember, when I call add, when I click add, it calls on add click. Now, now that I finally have
the value access to the value that was typed, which is just to do tax variable, right?
I can just add that to the to do list. Now we face another challenge because, okay,
the to do list is just static stuff here. It's just allies have no way of injecting
that new value here. How am I going to add an ally here? I cannot just hard code it, right? Because
it's runtime. So that's why I've got to do some changes here. We have to generate these allies
dynamically. We cannot just hard code them here. So what you can do is make an array of to do strings.
So every to do, we would just be a string that's placed within an array. So let's go up here.
I'm going to make a variable. I'm going to call it to do. Now it's an array. So square brackets,
right? So I'm going to cut to do to do the laundry here. Actually, I'm going to copy that
and place it here. I'm going to go back there, take walk the dog,
copy and comma, place it as a second element to this array of to do. Notice I have a quote,
right? Either double or single doesn't matter. Now I have a way to start them.
Let's create all these allies dynamically using the to do variable. So instead of writing them here,
I can just map here. So I do to do's, that's the array of elements that contain every to do string
dot map. And then I pass a function callback. Okay, I can pass an error function here. So
I can do parentheses, equal sign greater than and then some return value that's implicit. If
it's implicit, I don't need to type the curly braces. So I can do li here. Now I need to access
every element. So that's the first argument to this callback function. Let's call it just to do.
And then I can use that here in the ally. But if I just say to do here, I'm just going to literally
see the word to do. So in order to interpolate or substitute the value of the variable here,
I must use curly braces before and after the name. Now you can see do the laundry, the first
element and then walk the dog the second all transform our map into an ally.
Now this is very common operation to generate dynamic components based
off an array that's passed in with all the data. Right map is just an operation that iterates
goes through each element of the array starting from the first one. And then it will build a new
array with whatever values returned from the callback function here. So in this case, it's
building a new array with allies containing the to do from the original.
Okay, now that we have a place to store the to do's
all we have to do is push that is add to the end of this array of to do's. But again,
when you have stuff like this and react must keep track of stuff,
right to react to it and re render things, you must start this in the state. So we got to do
that same pattern, use state hook. So react dot use state this array, that's the initial value.
And then I must the structure here, because two things are returned from an array. So I want to
extract them into two separate variables. One is for the access to do's, the second to set
to do's that is change the value of that state.
Now, once I got that, I can use set to do's to push something to the end of this
array of to do's. So when I click on add click, I'm going to take the to do text,
and then I'm going to add to the end of an array that contains the elements from to do's
followed by the to do text. Now what I did here is I created a new array.
And I'm using this operator dot dot dot, which just means we going to copy all the elements from
the to do's. And then at the end, I'm going to add the to do text, which was the thing I typed
there. Now we can take this and set as the new value for the to do's. So I can say set to do's
call with this new array. Now in a click add, you're going to see it added there briefly, right?
See that? The click again keeps adding and adding and adding and adding and adding.
Obviously, this is not a very good user experience that we're going to change that
in a moment. But so far, how's everybody doing? Any questions?
Would it be possible to show how this would work utilize use contacts instead of use state?
So use contacts is a whole more advanced stuff for this lecture. But we can talk about that in
discord later. If you want to hang out there after the lecture, we can talk about contacts thing.
But for this use case right now is not so appropriate to use use contacts.
Use contacts is more for when you have deeply nested structures, you don't want to be passing the
data as a prop down, down, down, down, down, because it gets too messy. So you want to be
able to access the data from anywhere within the nested components. So that's when you use use contacts.
Anyway, let's fix this problem of adding stuff. So usually what happens when you click add is it
adds to the list, but also clears this so that the user can type something new.
Anybody want to guess how to clear this? Remember when I click add, it's setting the new
to do is here. And then I have to clear what was in the box. Remember the variable for the box is
to do text. And there's a function to change it set to do text. So therefore to clear that,
what would I call here to clear the text box? Yes, set to do text with an empty string.
Two quotes. We have that and I click add. Let me refresh this. Click add. There you go. Fine is clear.
Okay, now I just came across something I wasn't going to talk about, but that is
what happens if I click add right now? What is going to happen? Anybody want to guess?
Yeah. So this is weird, right? An empty bullet point. So maybe we want to prevent adding empty
things. So the way you could do that is maybe when you click add, we're going to check, hey,
did the user type anything? If the user didn't type anything, I just returned from the function
without doing anything. So I can go here and ask, okay, if to do text, right, that's a string that
length is zero, I can just return. I don't have to do anything else returns from the function,
meaning everything after return is ignored. We just stop halt, not going to do anything
afterward. So if I do that, refresh, try to add what an empty one, nothing happens because of the
return. Yeah, someone said, should we add trim? Yes. So what happens if I type an empty space
and click add? Oh, no. I hacked it to make it work. Yeah. So if you have blank spaces,
you can use the function dot trim to remove all leading and trailing space. So this would
be collapsed to an empty string. So you can always go here and say to the text dot trim,
call it like that to remove all that trailing space. So that if I type a single space that gets
collapsed to just empty string, and I don't I cannot no longer add just blank. So let me
remove and type some blanks with a spacebar, click add, nothing happens. There you go.
Okay, so we got add.
How about we add remove? Remember, I added some remove button there before the name of the to do.
We can do that next. We have some time. So I'm going to go here.
Remember the ally for to do inside the alignment out of button type button. And that's going to be
remove. Notice my environment keeps reformatting the code. That's, that's just this environment,
but yours might not do it if you're using some other kind of environment. It just when I save it
at three formats and styles the code a certain way. So you can see some parentheses were added.
Now I got the remove button there. I just want to add some style to put to make it not too close
to the to do. So let me do a class name, remove button, save that go to styles dot CSS dot remove
dash button. I want to add a margin right. Maybe eight pixels. Yeah, that's okay. 16. There you go.
And maybe the button looks a bit ugly. If you want to change that, that's a padding eight pixels,
16 pixels. It's up to maybe 16 too much. So up to you.
About that. And I'll add baby background color red and color white.
Oops, that's black ff ff ff ff ff or you can just say white word. Something like that. You can make
it prettier. Okay. Bar radius, or pixels, border, fix a solid black. Something like that.
Anyway, change it to your own heart's content.
Now let's add with a click, remove want something to happen. So add a non click
to the button on remove click.
Let's define it up here before the return function on remove click.
There's an event you want to put there.
Now, if I click on remove click, where we call now, let's think about this. So in order to remove
something, we must change the array of to do is right to do is in the state. So we must call set to
we must eliminate the one that we click to remove. Now we need to know what which one right that's
the problem here because I don't know I have no access to know. Okay, which one if cause if I click
remove the target in the event is the button itself. It's not this. So I must know the position I am
in some way. So what we can do, there are different ways you could leverage an attribute.
That's one way. Another way is you can leverage a function that returns a function.
Let's do the function returns function. So basically what happens is
we're going to go here on remove click. And we're going to call it as though it's a function.
And we're going to pass the index of the element we want to remove.
Now to access the index of this array, I must add the second argument to this callback here.
That's the index. So right away when it renders, we're going to be calling on remove click with
the index of the element that is first is going to call it with zero, then it goes going to call
it again with one. Now, when that happens, we must change the signature of on remove click
because no longer an event, that's best thing. It's an index and it's called right away. But if
you remember on click expects the definition of a function as its value. So therefore, when I call
on remove click with index argument, I must right away receive the definition of a function.
So therefore, I must return a function from on remove click. And this function is the one that
will handle the event. Some people like using the error function here. That's totally fine as well.
Now, if we do this, we have access to the index of the thing we want to remove. Therefore, I can go
there and take the two dues. And I can call out filter. And this function will filter out something
depending on the condition. So the argument is a callback. So we got the to do. And then the
second one is the index. Now this the to do index, let's call it that way because we don't
have a conflict with this index here. Index to remove might be a better name.
So let's call it. Now I'm going to make this as explicit return instead of implicit. So I'll add
the curly braces. Now, we must let pass if the to do index is not index. And then we take this
new array that's generated by this. And we use that for the set to dues.
Was that too fast? Let me change a few things here to make it a bit easier. So I'm going to
create a variable here filter to dues. And I'm going to cut this and paste it there. So it's
easier for you to see. And then finally, I'm going to set the to dues with the filter to dues.
So what's going on here? Let's go ahead again. So to dues is a variable that holds the list
or an array of to do strings. When I call filter, it's like the map, but it's a different operation.
We want to remove something. So the value that's returned here means, okay, I want to allow
to pass through. As long as the to do index, the current element index is not the one that I want
to remove. Maybe I should call this index to remove so you don't confuse it.
So this filter will return an array, the original with one less element. And that's the one whose
index, for example, the first one, right is index zero. So I click remove. And index to
remove here would be zero. Therefore, when I have zero here, the first iteration will be the first
zero not equal to zero. That's false, right? Because this is false. It doesn't get passed
through. It's filtered out. Therefore, the first one we filter out. And then the next one would be
what? Would be one. One is not equal to zero. True. Therefore, let it let it through the second
element. You're good. That's what's happening here.
Okay, so we can click remove. And it works. Any questions so far?
Okay. Now we got some time to do edit. Let's try that. Edit. Let's add a button here.
Scroll down where you have the remove before remove add another button.
Type button on click on edit click.
Edit button. Now I got to define on edit click. Function on edit click event.
Like that.
Now let's think about the experience here. When I click edit, I want this to be changed on input.
How would be able to do that? Well, we must kind of keep track of what I'm editing.
So we're going to have to say, what are you editing? Are you ready to the first, the second,
and so on. So I have the same problem as the remove. So therefore, we can try the same approach
here. Or if you want, try the data attribute approach. Let me teach you. So the data attributes
like this, you can add a data attribute here dash. And we're going to add the index
value there. So what I'm doing is pretty much
if I inspect that with the DevTools pressing F12,
I want to open this Li in the button here. Do you see data index attribute is set to zero for
the first one. And then to the second button is one. So that way, event the target is the button,
I can extract the data index attribute and get the index there. So this is another way of
doing solving the problem we had to remove. I just wanted to show you an alternative to that
function that returns the function. Okay, knowing that when we call an edit click, I can go to
event dot target dot data set dot index. Now let's understand what this is doing with a console
log here. I'm going to console like that. Okay. And I'm open the console with F12. Let me see
or click right click and inspect. And I'm going to. Oh, I got to click console here.
Console tab. I'm going to click edit for each one. Did you see the console log there?
Zero, one. So when I say event dot target, I mean, whoever I clicked right the edit button is the
target. It has a dot data set attribute that's actually holding all of the data dash attributes.
So if I want to access data index, I have to say data set dot index.
Okay.
So that's how we access that thing. Now I'm just going to leave this for reference for you.
Now, we must keep track of what we're editing right now. So I must keep track
like this. This is one way. Okay, I make an object.
And I set the property being the index. And I see if it's true
or false like this. I know this is a bit advanced, but what it's meaning. Okay, if I want to know
if the first element is being edited right now is in editing mode, I must have the value true set
for the zero property. And the second one means, okay, the second to do is not in edit mode. Edit
mode is false. Okay, so I must do that. Now we must keep track of this in the state. So we got to
do that same thing. React use state like this. And then cost. And we could call this editing.
And then set editing. Now I put initially for the first one that I need a comma here for syntax
that the first one is being edited by default. That's not really what we want. In fact, I could
just have left this object empty. And it would be set later as we click edit or not. So I don't
have to explicitly say this here, but just for the sake of our education here, let's go that way.
Okay, so I can use editing variable in the state to know if I'm editing or not. When I'm editing,
I want to show the text box with the value to do the laundry. Otherwise, I just want to show it
like this. So let's go down here, where we have the ally, the to do value. See that's to do.
So now it's going to be different. I got to only show that a certain addition. So if editing,
and I'm going to check, okay, at the index, if that is true, I'm going to use ternary operator.
If true, I must show an input type text with the value being the to do.
Now this might change later, but for now, just do like that. Otherwise, colon, I can just put a
span here or whatever with the to do. Let's see what's going on here. Editing
if I made any mistake, reactive state, comma, comma, cost editing,
ternary, oh, I forgot to put the curly brace at the end. Now you can see the initial state for
do the laundry is an input there. So I can edit. And the second one is walk the dog, which is just
the span. Why is that happening? Because I set the initial value for editing for zero to be true,
meaning it's editing mode on for the element at index zero, and then not editing, that is just
show the text for element at index one. Okay, now the problem is we can't edit, right?
Now that's another problem.
So one thing you could do is keep track of all these values for the text boxes.
But again, that's gonna, we can follow the same approach we did for this one. That's one way.
So if we do that, we would have to say, okay,
we're going to have an object, the first one would be some value, okay, that we're going to be editing.
And then the second one, another, but the problem here is we when we click edit, we must set this
value. So there's a lot of going on here that we're kind of out of time, but I hope we can
state to finish it. Let's see. So let's say editing text, set editing text like that.
And I must use react, use state.
Again, I didn't have to explicitly do this here, but for the sake of our education, I just put it
there so you know what format I'm using. Anyway, what's going to happen now is when I click edit,
I must set that value. But let's go down here. Instead of having value to do here,
it must be editing text at the index. See, it's empty now. That's because we got to do
some stuff when we click edit, we must set that value. So when click edit, calls an edit click.
So I want to set editing text, which is an object. Now it's going to be a new object
with the properties from editing text copied over, but I'm going to replace
the property for the index for this guy, which is comes from event target data set index.
Let's put that in a variable index here. And then I got to replace it here,
but I cannot just do index like this, to do at index.
I must add the brackets here. So the value of index is replaced here. In this case,
the first one would be zero if I click edit for the zero. And then to do at index just means,
okay, I'm going to go to the two dues, and I'm going to get the value for the zero, for example.
So I click edit, it's going to replace that there. See that to do the laundry. Obviously,
I initially had it true, but it should be false, like that. So I changed this to false here in
line nine. Now if I click edit, oops, not working. Let's see.
What's going on here?
Let's have a look what I messed up.
Put it in a variable, I put a comment.
Okay. Oh, what's the problem now? It's actually setting it, but I didn't set editing mode
true for this guy, right? Because that's set where? In this variable here, right?
So I must set set editing at the index to be true. So let's go there.
When I click to edit, not only we will be setting the value of the text box, we will be setting
editing mode. And we're going to create a new object. We're going to copy the properties over
from editing. And then we're going to go at the index, we're going to say true because we're
editing mode for that. I click edit, there you go. It's there.
I click edit for the second is there. See they're independent of each other.
Now the next challenge they're going to see is how to actually save it, right?
But how's everybody doing so far? Any questions?
You're welcome.
Okay, let's continue. Just finish it off.
So we must save it. Let's add a save button. There are different ways to go about the user
experience here. Let's keep it simple. We will add a save button here. So if you have the input
editing mode on, not only do I want to show the input but also a save button that I'll add after
the input. Type button on click, we'll call it on save click. And then we're going to say save
as the label. Now because I'm returning two things here, I must consolidate into one by either having
a div or a fragment. So if I do a react.pragment, I can return two things. Because in this case,
I must return only one because of JavaScript. So in order to do that, I must group these two things
into one thing. And one way of doing that is we're using what's called a react fragment.
When we use a react fragment, we don't create an extra div. You could also have used a div here,
no problem. That's totally okay as well. But if you use fragment, there's no div added to the DOM.
If I click edit, oops, what's going on there? There's I didn't define on save click. That's why
let's define that outside function on save click event. There you go. Now click edit.
There's the save button. Although it's a bit cramped in there, but you can see it.
If I click edit, there's a save. Okay, so let's think this through. I type something here,
right? Oh, I cannot type it because it's not controlled yet. Let's fix that. Remember, this is in
these inputs here. So I must add a what prop when I want to control it on change.
So we're going to say on, let's say, editing text change. Now we've got to say, okay, which one
you're going to change. So we can use the data index, or you can use the function return function.
Let's do function return function. So we must define on editing text change
with the index. And then we return a function that has the event as the parameter.
Oops, that.
Now I must say, okay, how do we change the text? Well, editing text
contains all the text for the inputs. So I must reference the object at the index. So I go here
and I'll say, okay, set editing text, copy properties over from editing text. But at the
index, I must set event dot target dot value. Because event dot target is the input, and the
value is what we type new there. If I go here and try to type 123, it's working. Now I click save,
right on save click. I must take this value here and replace in the original to dues.
Therefore, we must set to dues with a new array, but that specific one has to be replaced with
a new value. Now one way of doing that is with map. So I can say, okay, I'm going to go over to dues.
I'm going to map a to do. But then, okay, if the, let me add the index here to do index as a second,
if the to do index
is equal to the index of the thing I just changed, I'm going to return.
Oops, let's let's backtrack a little bit. So we got the value here
to the laundry 123. That's in editing text, right? So let's just have it here outside,
editing tax at the index. Now I don't have the index here again, with the saves, I must know
what I'm saving. Therefore, I must do the same problem again. Go to down to where we have save.
And on save click, I passed the index. Therefore, on save click now, must take the index here and
return a function with event like so, then we take all this stuff and put it inside here,
make sure it's inside this function. Okay, we got all this stuff inside. So if I take editing
tax with the index, that's what the new thing that I typed. So this new thing will go in here.
Otherwise, I return just whatever to do was before. Let me see if I was working.
I must also make sure to remove editing mode when I do that, right? So I must say set editing
to be dot, dot, dot editing. Sorry, I'm going too fast because I'm trying to wrap it up,
but editing at the index, it's false. Let's try that. There you go.
So walk the dog, one save, there you go.
So when I click, when I type something here, do the laundry today, I click save, save will call
and save click. But remember, on save click was already called with the index for each one. So
therefore, I actually have a function that's returned. So when I click save, it's actually
calling this function inside. And then what I'm doing is, okay, I take all the to dos original
ones, I going to map, meaning I'm going to transform each one. So what happens is, okay,
if nothing special, I just return how it was before, right? As I'm transforming them, I transform
into itself. There's no change. That's why I return to do here. But if I find that I'm iterating
through and I find that specific index to do index that matches the one I'm editing or clicking to
save, that means Oh, in this case, instead of returning the original, I will return whatever
the user typed into this input, which is in this object editing text at the index for this guy.
So this whole thing will include the array with one element being the first element here,
replaced with this value here. And then I use set to dos to replace the original. Then after that,
in order to close this editing mode, bring back the other thing, I must set editing, right? Because
editing is like editing mode shown or not, for that specific index to be false, meaning don't show
edit again anymore. So I click save. And that's why I've got today there. Now all of this happening
react is doing everything for you because it's reacting to all the state changes, right? When
I call set to dos state changes, re-render. When I call set editing, say changes, re-renders. That's
why I no longer see the input because this value was changed, the state changed, and then everything
is re-rendered. So by the time I reach this part where it's checking if I should show the input
or just the plain text, it's hitting just the plain text because editing at that index was changed,
right? To false. This value is now false for the first one.
And it works independently of each other. So you can be editing multiple things at
the same time. And it works. Just for each one.
Okay. So that's it. The to-do list, everybody. Sorry for going a little bit over time. I hope you
appreciated this.
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? ๐๐
Consider a donation to support our work: