Loading
Lesson 10
Courses / Software School
Further Introduction to React (Chat Room Message Board) [raw] - Software School (2024-04-11)

Introduction: The session starts with a brief overview of React components, state, and props. The goal is to build a simple chat room.

Setting up the Environment: The instructor guides the audience through setting up the code sandbox environment, explaining the file structure (index.js, app.js, styles.css), and how code changes are reflected in the output.

Basic Component Structure: The instructor demonstrates creating a basic React component by defining a function that returns JSX (JavaScript XML), which looks like HTML but is rendered by React.

Rendering Data: The instructor introduces the concept of state using the useState hook to manage an array of messages. They demonstrate how to map over the array to render each message as a div element.

Fetching Data: The useEffect hook is introduced to fetch data from an external API. The code fetches a list of messages from a provided endpoint and updates the component's state with the fetched data.

Styling: Basic CSS is used to style the components, including adding classes and applying styles to the message container, individual messages, and the input/send button.

Adding User Input: The instructor adds an input field and a send button to the component.

The tutorial delves deeper into concepts like:

JSX: How to write HTML-like syntax within JavaScript. State Management: Using the useState hook to manage and update component state. Side Effects: Handling side effects (like API calls) with the useEffect hook. Data Fetching: Making HTTP requests using the fetch API. Styling with CSS: Applying styles to React components using CSS classes.

The lesson also dives into event handling in React, a fundamental concept for building interactive user interfaces. Here's a breakdown of the key points:

Event Handling Mechanism: React employs a synthetic event system that offers a unified API across different browsers. This ensures consistent event behavior regardless of the underlying browser.

Event Naming Conventions: React events adhere to camelCase naming conventions. Event handlers, the functions that execute in response to events, are prefixed with "handle" followed by the event name (e.g., onClick triggers the handleClick function).

Attaching Event Handlers: Event handlers are attached to elements using JSX syntax. The event name is assigned to the element, along with a reference to the handler function within curly braces.

Event Handler Functions: These functions are defined separately or inline and are responsible for the actions triggered by the event. They can access component props as they are defined within the component.

Event Objects: When an event handler is invoked, it receives an argument called the event object. This object encompasses details about the event, such as its type, value, target element, and ID.

Key Points to Remember:

Event handlers are passed as props to elements, not called directly within JSX. Event handlers can be defined inline or as separate functions. Event propagation follows the bubbling phase by default. To capture events at the capture phase, use the Capture suffix (e.g., onClickCapture). React events might have default browser behaviors that you may want to prevent using event.preventDefault().

Video Transcript

Okay, so today we'll talk more about React. We had a session before, which was an introduction to React, so we'll pick up from that. So kind of showing me how to a little bit of the basics, like how to make a React component, what is the state, how React will render it as it reacts to a change in state and a change in prop. So we're going to build today something like a chat room or a message board, where we have like a container for the messages or text, and then the bottom you have some text input where you can say some message and click send, and then it will be injected into this container here. So to do that, we'll practice several of React's way of doing things. Yeah, I said it before, the recording we posted to the YouTube channel, but if you want the recording right away, please send me a donation, and I will send you the link. Otherwise, you have to wait a couple of weeks for the edited version. Okay, here's the links again, in case you haven't got, oops, that wasn't for you, Satish, sorry, it automatically changed to you. There's the link. Anyway, yeah, React, and let's go here. So we can see this code sandbox, the left-hand side is the file browser where you can see other files explorer, and there's the source directory, there's index, this is where everything begins. And if you look at public slash index.html, and look at the body, you're going to see this div that has the ID attribute root. So this is the React application is injected. In this code sandbox environment, the right-hand side is the output from your application. As you change the code in the middle panel, you will see it update accordingly on the right-hand side. It's like a mini browser within the browser. Okay, if you go to index.js, under a source, you can see here there's a document get element by the root, meaning it grabs that empty div, and then it injects the React application. That's pretty much encapsulated in this app component that we can find in app.js, if you look here in line four, import app from dot slash app. And we go there, we can see there's a function app. So React components in its most basic form are just functions that return some kind of template for the view that will be rendered. Functional components has been now the preferred way of building React components. Previously in the past, React used to do class base, that is, we will build a class and then instantiate an object for the component, but that's no longer the preferred way. But you can still do it, although they prefer to do it the functional way. In the functional way, just create a function that returns the template of something that looks like HTML, but isn't really HTML. It's what we call JSX, which is JavaScript. It's actually a function called to react dot create element, but it's kind of syntax trigger that's hidden behind the scenes. So you can write it as though it looks like HTML elements with attributes. In the world of React, we call these elements components, and we call the attributes props. Somebody asked, recording, you will send an email. No, the recording will be on YouTube, the YouTube channel. I posted the link. Okay, so click on YouTube there. Let me post it again for you. The recording will be sent published to that YouTube channel if you want the recording right away, because it takes time for me to edit. If you want the raw unedited version, send me a donation, and then I will send you the link, maybe via zoom message, or whatever other means of social media you have. Anyway, continuing here, let's just delete everything from this. We could just say hello world here inside this div, and you're going to see the right hand side, hello world there. Let me see if you can make it bigger. Okay, so our goal is to build this kind of chat. I want to start off with the upper part to hold the messages. So basically a container, we can start off just using divs. That's not a problem. And then we're going to get the other messages from an API, the initial messages. And I'll post the link soon. In any case, going back here, looks like this environment has format don't save. So it changed my code, as I saved it. All right, so for the API here, let me post on a chat. We're going to use that endpoint. But for now, let's just pretend there are some messages here. So we're going to start off like this, we can add some style here, if you think, let's add a class. Now, if you want to add a class in react, you have to use class now. So we're going to start off like let's add a class. Now, if you want to add a class in react, you have to use class name instead of class, because classes have reserved keyword in JavaScript. So let's call this app. And then it imports style here dot CSS, so you can use that file to define in CSSc1. Actually, they have dot app here. So let's use that instead. Going back, I'm going to use uppercase A here. Going back to styles, I'm going to delete all these things. And let me put a board around it on pixel solid black. And let's add some padding, maybe 16. Oh, maybe that's too much. Eight. Yeah, maybe that's okay. Just to make it better. For the height, if you want, we can make it take the whole viewport. Like that. Although it's a bit too weird here. We can do fix for now. Let's try 400 pixels. So you have a certain height. Anyway, I'm going to save that. Going back to app. Now, let me add just one more message in a div, third mess. Hello there. Now, we're just mocking this up. This is eventually going to come from the server. So the first step here, if I work from the front end towards the back end, because all the data is going to come from somewhere in the back end. Imagine you're coming into this message board or whatever. The messages have already been posted. So there are some initial data there. So what we have to do is, okay, we come in in the client, make a request to the server or back end, and ask for the messages, and then we can take them and render them here, one inside a div for each. Now, the way I usually approach, if I just I'm strictly front end developer, I would come up, okay, make a mock like this, a fake, and then I would go backwards. Okay, this is nice, but it's going to come from somewhere and that somewhere is probably a sequence of things. So I'm going to think about arrays in JavaScript arrays or sequence of elements. So maybe I want to create an array here outside, let's say messages. And then we're going to take all of these and make a string element for each. And then finally hello there. Now I usually like to make them into a new line because it's easier to see. Now it's nice to how can we transition from having hard coded data here from taking the message strings and converting them to a div element each. Now we can use a map operation if you ever do a JavaScript, that's a function called map on the arrays, that we can transform each element of an array into something else. What we're going to do is transform every string into a div whose content is the string. Now I'm going to delete all of these, and it's going to be gone there. Now what we're going to do is if you want to do some operation here with the messages, you have to use the curly braces here. For example, if I want to show the first one, I would say messages bracket zero, right? Because in the world of JavaScript, when you have an array, my messages is a variable that holds an array. If I want to access the first element, I have to say the bracket notation with the index inside, and the index always gets counted from zero. So the first element is at zero. So this is the way I would do it. If I don't have the curly braces, I would literally see the messages bracket zero there. So in order to interpolate, that is substitute the value of this variable there, I must have the curly braces when I am in the context of JSX, that is in this kind of HTML lookalike inside the return here, that is the JSX. Okay, that's nice, but I want to be able to do all of them. So instead of doing just the first, I'm going to do a map. So I'm going to take that array and dot map, and the map function takes a function as an argument. You can either use the function like this or an arrow function, either way. The arrow function will be like this, and then it can implicit return something. Well, the argument would be the element, in this case, let's call the variable message, and then we would create a div here with the value message like that. Now I wrote it in a very compact way with the arrow function. You are free to use the function keyword with an explicit return that works the same way. If I don't like the compact version, I can go here and say return like that, and it should work the same way, okay? Let me revert my change. Okay, nice. Now we are able to translate, if we're given an array, we can map them to a div here. Now it would be nice to have some space between them, so I might want to add a class name here. Let's say, let's call it message. And then I'm going to go to the CSS, create a new selector dot message dot means class. So whenever an element has the class message, I want to add maybe, maybe I'll add some margin bottom of six pixels, so they're not so glued together, something like that. Then you can add more styles if you see fit. Okay. That would be nice if I could word wrap here, because it's, I don't like scrolling here, in order to see, I don't know where the settings are here. Settings, editor, word wrap. Let's see. Oh, there you go. On. Oh, there you go. Now I have word wrap, so it won't require me to scroll. As you can see it here, it's breaking to the next line. Anyway. Okay, anybody have any questions so far? Is it okay? Okay, so I'll keep going. All right, so this is nice, but we still we must get these messages from a server. So how do we do that react? But typically, if you want to fetch or make a HP request, it's called a side effect. So they have a whole called use effect for that. So let me try to make use effect. Call it like this, and it pass a function as the argument, can be a function keyword or error function, doesn't matter. So if you do it like that, let's see. Our react is not defined, so we have to import react from react. Let me just do something here. Let me try to put a console log react, use effect to see if it's being called at all. Where's the console? Oh, no, I don't have access. That sucks. Anyway. Okay. So a react function component will render and return the template. But every time the state or props given to this component changes, it will re render it. That means this function will be called again. Now use effect is something that is called every time after render. So if this component renders again, this function that's passed to use effect will be called. But now usually when we fetch data, we want to call it only once. So that means the component mounts, that is has the first render, then we start fetching the data. And then we're done. We don't want to fetch data again after the second render, because it'll be crazy like every time something changes in the react component, like the state or props, which happens very often. It would be getting the data again, and we don't want to do that. So the second argument to use effect hook is an array of what's called dependencies. So what it means is if you pass some variable here, that's a dependency meaning if that variable changes, then we call this function. Now if you leave it empty, that's a special case, meaning it only runs once after the first render. And that's what we want when we're fetching the data. So the moment this component mounts, it's going to fetch the data. Okay, but before we get there, we need to find a way to store the messages in a way that if we start off initially with empty messages, right, because we haven't fetched them from the back end server API. And then we use effect to make load that data, grab the data, and then eventually want to inject them here in messages. But react must know when the value of messages changes. If you do it normally like this, messages equals whatever, for some reason I reset it, react will not know that you changed messages, because it only keeps track of state and props. So the only way for react to react to the change in the messages variable is to place that value in the react state. Okay, once it's in the state, react is tracking it. So it will detect Oh, you changed the value of messages. Now I'm going to re render. Okay, so we must place messages under the state. Now to do that, we use another hook, a H o okay, that's called a use state hook. So here, for messages, I would have to do react use state. Now the way it works is first you pass an initial value. Okay, I want the messages to be an empty array at first. So square brackets. Now, when I call the use state, it returns an array of two things, two elements. The first element is the variable to access that value for messages. And the second is the function to change that value. Now what people typically do is they destructure, it's a JavaScript thing that we can use like this notation, messages, set messages, meaning it will take this right hand side, it's an array. So we'll take the first element and store that in the messages variable, it will take the second element and store in the set messages variable. Now I named these messages and set messages, because I think it's very descriptive of what they are, you can name it whatever you want. The convention is, okay, what's what you're storing is the messages. And then I always named the second the function to be set, followed by whatever this name is set messages. And it's always camel case, camel case, meaning the first letter is lowercase and every word that follows the first letter is uppercase. Okay, now we have that in the state, I'm going to delete the plane array there. Now, with this in mind, I have a messages that I can access that it's initially empty. And you can see here the mapping operation, there's nothing on the screen. But if I added the initial state here, you're going to see it's there again. Okay, I don't want anything for initial state. So I'm going to remove it. So it becomes like that again. But to demonstrate that set messages works, I'm going to delete this console log here. And I'm going to call set messages here with that array of restrings. And you can see it's appearing here why to understand why I'm going to add a set timeout here. Set timeout is a function that you can place here, for example, after five seconds, that is 5000 milliseconds, I want this function that I passed as this first argument to set timeout to execute. So I'm going to move the set messages inside just to demonstrate that's actually doing something. So it's going to be a delay of five seconds. So initially, the component's going to render with messages being empty array. So you want you won't see anything because it finished rendering, it's going to call the use effect here. And it's going to call a set timeout. And it's going to wait for five seconds. And then then it's going to use, it's going to call set messages and finally set them. Let's save and see that. Okay, set timeouts. Let me refresh. Wait five seconds. There you go. So five seconds later, finally set messages was called and you can see the moment you change the state set messages as a function that changes the state for the messages. It changes to the array of three elements. That moment that happens reacts knows, hey, the state was changed, we must re render. Therefore, now messages with the three elements will be rendered here because the map operation will see there's three elements and will render div for each. That's why it appeared there. So in the DOM, everything is automatically updated for you. If you were to inspect that, with the dev tools, you could see the DOM changed because react is in charge of doing that change for you. You don't have to worry about the DOM at all. That's all taken care of by react. So if I do it again, refresh there, and inspect this part, you're going to see there's nothing there. After five seconds, you're going to see it injected all the divs with the class message there. And that was all done by react by reacting to a state change. It re rendered. And what happens is it has kind of like a virtual DOM that is listening to the difference and wants to see a difference between what you have in react and what's in the DOM, it will sync them and make the DOM change accordingly. Does anybody have any questions so far? Okay, I'm going to keep going. All right, so the next step is to actually get the data from the server. Now I'm going to remove this time out because you already saw that it's actually doing something. What do you want me to explain? Yeah, use the fact as a hook, it's okay. So react is a function here, there's a function, a component is a function, and that is called to return some kind of template or view. So the first time it renders, it does so with the messages being an empty array here. Use effect is used for side effects. If you want something to happen like fetching data, that's like a side effect. So when you use use effect, you pass a function as the first argument and the second argument is an array of dependencies. Now the special case of the array being empty means I want after the first render of this component to call the function that I pass to use effect, but all the other subsequent renders I don't want to call it anymore. Okay, so use effect is called after renders. If you want something to happen after the component renders, like the fetching of data on the initial render, you fetch the data, usually we only do that once. That's why we make the array of dependencies empty. So that use effect is not called again, on the next renders, because it's going to be rendering out the time when the state or props change in a component. And we don't want to be refatching the same data over and over. It's just once just in the beginning. It will know it's not render once it will be the function called by use effect will be called after the first render if you just pass only after the first render if you pass an empty array. So we want to do something after the first render what we do use effect pass a function and the second argument is an empty array. That's it. It only calls this once and after the very first render no more after that if the component renders again it will not call this. Okay. All right, so I'm going to keep going. Okay, it's time for us to remove the time out. And we're going to do the actual fetching data from an API. So typically that's what happens. We have a server somewhere that holds data in a database. So we need to call on that server or back end or API. Hey, I need to access this resource. In this case, I want to access some sort of message or post. Hey, I need all the posts that are posted to this specific place. We're going to ask for that. And that's via HTTP request. And then we're going to get it back. And then what we're going to do is set messages with that information. So the API application programming interface that we're going to use is this one that I pasted in the Zoom chat. We're going to use that endpoint URL. If you click that, that's going to go and give you a response. It's like fake data. It's not real. Okay. It's just somebody wrote and published that and it's running that server to help people in the education and beginners understand API stuff and use it for testing purposes. So if we go there, it's just a JSON. Here's the raw data. Let me increase. So it's an array of objects. And each object has some information about a post, like a blog post, message, whatever. And we're interested in just getting some dummy data. And the data I want to get is the title here. You see the title property has a value that's suitable for what we're doing right now. So we're going to go and get all of these and we're going to inject into our application. So going back here. In the user fact, we're going to, okay, how do we make a request? We can use the fetch API. Okay. So you just call fetch like that. It's a function that we call. And then we need to say, okay, what do you want to fetch? What's the URL? So you pass the string with that value that I post in a zoom. That's the endpoint. Now, once we do that, we're going to get a response object. Now, that response object is injected inside a promise. So promise is something like takes time to like you want to make a request, okay, it goes and asks for the server, but that takes time. So we got to wait for the response. So while we're waiting, the promise is still pending. Okay, we promise you to give you something, but you got to wait. So we're pending until it fulfills if you got a response, the promise fulfills. So the way we can fulfill a promise and handle that is if you say dot then here. So the return value of fetch is a promise. So if you want to handle that, you call dot then, and then you pass a function inside the parentheses here. Let me increase the size, maybe like this. There's a dot here, okay, it's just that's in the other line. So okay, once I get a response from this, I want to handle the promise being okay, then the response is the argument to this function. And then we need to do something with the response. Okay. Now the response, we know it's going to be in JSON format, but initially it's just a plain text. So we need a way to convert that to JSON object, a JavaScript object. So what we're going to do here is return response dot JSON function call like this. What this does is it takes whatever the body of the response and converts and takes that and converts to a JSON JavaScript object notation. So that means we it also returns a promise. So we can add another another dot then here to handle that promise. And that will be the response in JSON format, which is basically the posts, I can name it posts like this. That's totally fine. And now there's going to be a ray of objects like we saw if we remember this, I mean, just copy this so you understand what it is. Let me put it as a comment. Basically, it's going to be like this. Post is an array of objects, but I'm only interested in title here. So I'm going to map over these. And I'm only going to get the title. And I'm going to set messages with that. So I'm going to say post dot map post. Now I only need the title, I don't care about anything else. I'm going to say post dot title to access that. Now I'm going to say set messages with this. Maybe it's easier if I put this in a variable. Maybe I say titles array like that and set messages with the titles and I'll remove this thing here. There's a lot of them. So it's pretty long. So maybe for the sake of our learning, I'm going to just limit that. I'm going to put maybe slice 0 through 10 like that. Just to eliminate all the other ones, I'll just take the first pen or so. Okay. Let's see if we have questions. It might have been too fast. Was the object called post or post? So let me try to debug this for you. I don't know if I can do it in this environment, but I will try. Usually to debug this, I press F12 to open the dev tools. And I can go to source or debugger in Firefox. I'm using Firefox. I don't know if I can see this code here. Let me see. React app. What is this? Send box. Now this is hard to debug because it's in this environment. So let me try to explain. Usually we can also console log, but this environment doesn't let me see. So was the object called post or post? Trying to understand what the JSON looked like and why you use post. Yeah, yeah, yeah. So when I call fetch here, it returns a promise with a value that will be fulfilled. And that value is a response. Now we get the response. And then we handle the promise by using dot then here, meaning, okay, whatever we got from this promise that was fulfilled, take that value. And we're going to call the function that you pass to them. And the value from the promise will be in this variable here that I called response. Now the name of the variable doesn't matter. I can call this whatever. You can call it whatever. But you have to understand that that is a response object. So that's why I like to use the name the response because of the descriptive. Now this object is had information about the response metadata, all sorts of stuff. What did you call? Where did you call? What did the server say? All the headers from the HTTP, whatever. But there's also the body of the response, which is what we see here in the browser if we go to that URL. We see it's just a text, right? It's plain text with something written in the JSON format. But for the purposes of the body of the response, as we see it initially here, that's just text. It's nothing special. So what we do is, okay, I can make that text, extract the text from the body, and then turn that into a JavaScript object. And to do that, I can call JSON, this JSON function from the response object. If I call that, what's happening, it returns a promise that fulfills with a value. The value is the extracted text converted to a JavaScript object. So that's what happens here. When I say that then the value that I return here is the next goes to the next call then. And this variable posts, I call it posts, is whatever I extracted from the response body, transform it to a JavaScript object. In this case, because it's an array, right? It's an array. It's not an object in the top level here. It's going to be converted to an array. You know, array is an object in JavaScript. But that's what happens here. So this response dot JSON call here will fulfill the promise here with an array of all those objects, post objects. Now the name here doesn't matter. It can be whatever. Like I said before, you choose, I choose post because it makes sense to me. It's an array of posts objects. Now, when I say post dot slice here, I'm just taking all the elements and take there's so many elements, I don't want all of them for the purposes of our instruction here. I just want the first 10. So I slice the array, meaning I take, I take from element zero all the way to 10 minus one. I don't include the element of index 10. So it's basically taking the first 10 elements. And then finally, I do a dot map, meaning I transform each element into something else. In that case, I need to pass a function that has a variable. And that variable is just the object, every element of the array. I can call it whatever as well. Doesn't matter. But here I understand this is an object that represents the post, right? So post here, going back to JSON would be this one at first. And then the second iteration would be the second one, the next iteration, the third one, all the way to the 10th one. Okay, so as I understand it, each object, I imagine this is stored in the post variable, has the proper title. So I want to extract this value here, right? So I need to access post dot title here. So that's what I do here, post dot title, and I return that implicitly via the arrow function here in this mapping operation. So I turn all of these objects into strings of these values here. Let me try to get it, maybe it's helpful if I do it on the console here, I open my console, and I'm going to say post array, I'm just copying whatever was there. You see this? Oops. I put, I copy this, I put posts here. And if I say posts, it's an array of three elements, and each is an object here. You can see there's a title, right? So if I do, now, to get out of this, going back, if I do post dot map, passive function, let make it explicit for you, maybe it's easier to see function, post, like this. And I say return post dot title. See what happens. Now I get an array of three elements, each being a string. And those are the titles that I extracted. Okay, does that make sense? All right. Going back now. Not this one, this one. Now finally, once we get all the titles extracted, an array of titles or messages, I finally call set messages with that array, so that I get these, all these values here injected as a div each. All right. And that's how you get initial data from the server. Now it would be nice to use other things. You see there's user ID, there's even body if you want to expand the message, but we're keeping it simple. You can do it as an exercise, try to leverage all these other information and add them to your container of messages. Maybe if you click the message, it will show the expanded body, the body information. Maybe you can say the user who posted it, user ID, whatever. Although this one only has the ID. But if you go here to this and say slash users, you can also leverage raw data for users here. This is a little bit more stuff you could do later if you say slash users there. But enough for that, I'm going back and focus on the next step, which is us writing a message on the spot and injecting it to the already existing list of messages. If you remember, that's the bottom part here that I'm going to do now. Okay, so I'm going to go here. This is kind of, I want to separate this container maybe into another one. So if I put a div here, just for the text box, input type text, like this, and then a button, maybe, button type, button send. Now you can see here, I wanted to return two things from the component. I want to render the container for the messages and the container for the text box and the send button. But it doesn't let me because in JavaScript, you can only return one thing. Now there are different ways we can approach this in React. One way is you could maybe return an array, make this an array of two things that works, right? The first element is the container for messages, the second element, the container for the send and text box. Now there's another better way instead of a race, and that's using react fragments. Actually, there's a standard way, which is just putting a div here and placing all of these inside a div. That works, right? The only downside to this, if you care a lot about a nested div that's unnecessary, like the problem with this is you got, if I open the dev tools here, I got the message container and I got the other one, but there's an extra div here that I don't really need. Some people really take issue of this. That's why they created react fragment. So if you don't want the div there, all you have to do is say react.fragment here and make sure to close it the same way. So if you use react.fragment, what happens is there's no extra div there. If you inspect the dev tools, you can return multiple things and there's no, look, you see there's this and that inside the roots and there's no extra div in between. So that's the react fragment to return multiple things from a component. Now, some people, you probably see this in a different name is some people are very lazy. So they would don't want to type react fragment. So they just said, okay, let's just have the tags be empty. And that's the same thing. Okay, so if you see empty angle brackets like this, it's just react fragment, same thing. Laziness taken to the extreme, you know. All right. Nice. So let's make this button here take over the whole have a better style. So I'm going to do maybe what can we do here? Class name for the send, let's call it send box. I will add some to the style.css send dash box class. I want that to take over the whole width of the thing. So maybe I'll do display flex. That's one thing. And then to the send box, assuming there's only one input, I can just put the input here. But that's not good practice. I usually want to use a class, but since we're just doing things quick, I assume there's only one input there. I'm going to say flex one. So it takes over the whole line. Now the input is also I likes more padding. This is a bit so maybe a little bit padding there. Maybe more about we do it. Yeah. And the send button, let's do dot send box button. Assuming there's only one, I would ideally add a class to the button instead of targeting like this. Let's add some padding as well. Top to bottom, maybe six and then 12. Like that. It's a little better. If you want to add some space, your touch up is up to you. We're just keeping it very draft like here. Anyway, going back here after finishing some styling, I want to be able to type some text here and click send and inject this there. Now let's think about that. So I click send. That's a click event. So I'm going to have to handle the on click for the button. So this, I add an attribute or what we call in the react world a prop. So in HTML, it's usually all lowercase, but for react, we got to do camel case. Now in react world, we have to pass a function whereas HTML is a string. So we're going to say here on send click, and we're going to create this function. Note I don't have parentheses here. If I have parentheses, going to call the function right away. That's not what we want. We want to only pass the function definition so that the button will listen to the click and then only call it when it's click. So in the world of function components, we can define the function inside the component function itself. So on send click, typically there's an event argument. And there's the function there. Now if we're in a normal environment, you can put a console log here and put on send click. Whoops. Copy this. And every time you click, you're going to see the console log that. Unfortunately, this environment, I don't think it can access. I don't think that works here. Oh, it works. Actually, never mind. So if you click send, you can see it's being called because you can see the message on send click that I put here. All right. So every time you click send, the function on send click is called. And if you want to look at the event, you can also call my here event object to better understand what event is. You can see object event is an object. And that has all these properties, blah, blah, blah, whatever. If you care about that, I don't really care right now. I can see target is the button, the thing that triggered. All right. So we need a way. Okay, we're going to click send, right? Let me remove this console line. I need to grab the contents from this and put in that container, which the container is basically the messages. So I need to find a way to message push, right? The new message, which will come to somewhere. This input. But how can we access that? Well, in the world of vanilla JavaScript, you can do like query selector or document got lmid, this element here, and then grab the dot value. In react world, we should not do that. Don't do that. Don't use query selector because you're bypassing react. So react won't know what's going on and won't be able to react to changes accordingly to re render. So we want to avoid that. Instead, what we want to do is control this component with react. So we're going to control the input. Now to control it, you need to set the state with the value for the input, the text that will be typed as well as a function that will be called every time you type so that that state value is changed on every typing. So we're going to go here to the input line 30, we're going to add a value attribute or prop. And that has to be a state variable. Let's call it a new message to differentiate from the other one. Now we need to define this inside the state. So we're going to go up here. Line five, I'm going to break in line. Let's use the same method you react dot use state. Now I need an initial value. Usually it's empty string for inputs, right? We don't want anything to show initially. And then this is going to return what we call tuple, right, a two element array. So we can destructure that is extract the first second element, we can use the syntax with the scribe brackets const. Let's say new message here, comma set new message, which is the function to set that. Now, if you do that, by the way, some people like to use state without saying react dot. But how can we do that? Well, you have to go into the import line to and use the named import export here, use state. If you want to use it like this, you have to import like this from react. All right. That's another common way people do that. I don't like doing that, especially for beginners, because people don't know where things are coming from. If I look just at this line, I might be in a code somewhere. And you're a beginner, you don't understand where things coming from coming from. So I prefer to explicitly say it's coming from react. Okay, now if you notice here, if I try to type anything, nothing happens, because there's no function handling this, the value is forever stuck to the initial value here. So if I put hello for the initial value, it's going to appear hello here. Because new message is being associated as the value for the input, it's forever stuck that way and cannot type it unless we add our own change. So let's add an own change prop to the input. And it has to be a function that will handle the changing of the text. So let's say on new message change. Now we have to define this function here. Up here, I'm going to say function on new message change with the event as the argument. And then what what's going to happen, let me console live for you. So you can see how we can extract the value there. So I put a console log of the event value here. And we're going to do try to type something as I open the DevTools with F12. And let me clear this, I'm going to type a, you see something triggered there, because this function was called when I type a. Now let's see what's inside the event object. There's a lot of stuff, but what I care, do you see this target? If I open target, I'm going to eventually get some property that's called a value. There's so many properties, kind of tedious to go through. But you can see the value here. Hello, that's what we want. So if we go to event dot target dot value, that's how we get what the user type. So event dot target dot value. Now we need to assign that to the new message, because we need to change this new message here. So we call new set new message with the event target of value as the argument here. Now when I type, well, it's now changing. Because when I type one letter, every letter I type calls this function, it takes whatever I had typed and sets the value of new message to that. So that it re-renders, right, because the state was changed, React will re-render the component. And what we will see here is what you typed. So if I type X, calls this function, set new message with the X there, and then re-renders. And then the moment we re-render the input, the value will be with the X here. So you're going to see here, imagine this substituted the value of the X at the end here. So that's why we see it. Okay. Now I revert that. That's cool. But now let's handle the send. So on send click, remember, it's called when I click send. Now I need to push to message here. But I cannot do it this way. Okay, I have to do set the react way, which is you have to call the function to change the messages, which is set messages. So here I have to say set messages with the new value for messages. Remember, message is an array. So if I say just a new message, remember, if I want to access what they use, what you typed, you just call, I just use new message now, because we have that in the state. Now this is not going to work because this is going to set the whole message state to be just one string. So that's not good. That's going to crash the thing. See, when they say message.map is not a function because messages now a string single string, we want to be an array. So you want to keep that an array. Okay, wait for the brackets. Now if I do it like this, it's no good because it's going to wipe out everything. Everything's gone. You only have the new message. So you need to copy the existing messages and add to the end the new one. So there are different ways to do that. One way is using the dot dot dot. That means, okay, I'm going to take whatever elements were in messages, dot dot dot messages, comma, add to the end the new message. Okay, the dot dot dot means, okay, take every element of messages and inject into this new array, and then comma, add this new element to the end. Now when I do that, click send, it's added to the end here. And I keep going, hello world. Does anybody have any questions? All good? Yes, you asked, don't we want to clear after we click send? That's what I got, I was about to ask you next. Let's do that. So typically, when we send something, we want to clear this, right, if it's successful, right, typically, this would call the back end server, and we need to see if the server approved it, if it's successful or not. If it's successful, we can clear and then inject. Because we're doing something very simple, we're not calling the back end to inject the new message. So this is very silly. But okay, when we have the send click here, after we either before or after, doesn't matter, let's say for everything successful, you want to clear the new message, we want this to be empty. Does anybody want to take a shot what you would write here to clear the input of the new message? Start S, E, no guesses, clear this input. So what variable is associated with value there? Yeah, almost. Yeah, so the value is new message, but we don't want to call the function set new message. But it's a function. So we must call it with parentheses and empty string, either single quotes, single quotes, or double quotes, double quotes, doesn't matter. Yeah, you almost got it right. But the syntax is different. It's parentheses because of function. Okay, let's try. Hey, whatever, send. Okay, injected and cleared. Nice. Yeah. So typically, in the real world, what would happen is you would call fetch here, make a request the back end, hey, I want to add a new post. And then they would say, okay, you're fine, you can do this, otherwise, or they could send you an error. And then we would have to handle the error. Maybe we would show error message here. And all that kind of stuff, we have to show a loading state, meaning, okay, after a click send, I want to disable the button, I want to show some sort of loading state, maybe. And when I want to get the response, that's when I enable the button again. And if there's an error message, I show it maybe here at the bottom, I mark this red or something, stuff like that that you can build upon this project. By the way, should we always you patch and use effect? Yeah, so if you need to patch data in react client side, make sure to do so in use effect, because that's the whole point of use effect is to do side effects. And the loading of fetching of data is a side effect. You want to take that a little bit outside of the rendering, because the problem is react, it keeps rendering all the time and calling the same function, right? The component function keeps getting called because there's so many interactions and state changes. So it keeps reacting. And if you had the code for fetching data somehow, booting there every time you render, it's going to fetch data, render fetch data, that's not very efficient. It's going to be a mess. So that's why they made this thing for side effects. Okay, if you need to fetch data, you know, kind of outside of the rendering thing, you have to use use effect. Yes, you can use multiple use effects, as many as you want, and you can add different dependencies here. Maybe you can react to different things, maybe some other variable in the app change somewhere, and you want to update something, because of that change, you want to react to the change in certain state variable, and do some side effect, that's when you use use effect, you would put some variable here. If this variable changes, this function for the effect will be called to update whatever you need to update in response to the change in this variable. So you can have multiple use effects, that's totally fine. With different dependencies, maybe I depend on something else. And I do some when something else changes, I do something about it. In the world of a class based components, what react used to do that this use effect that's only called once after the first render is component dead mount, the lifecycle. The other one that gets called every time something changes is the lifecycle function component did update. So if you ever work with react class based components, component did mount, and component did update are the equivalents of the use effect. So react is rendering the all the messages every time. It only renders when there's a change. So it calls render or call this function when there's a change in state, or the props given to the component. So it reacts to those changes and renders again. But it's not always rendering all the time if you're asking if that's the case. No, it's not always calling the render function itself. It only calls when there's a change in state or props. Yeah, react as a virtual DOM, the capacity real DOM. Yeah, there's all this of this to kind of things that it keeps comparing to to determine if the actual DOM in the browser will be changed to to be updated with the react tree. All right. So I think that's it. You
No comments yet (loading...)
No comments yet (loading...)
Did you like the lesson? ๐Ÿ˜†๐Ÿ‘
Consider a donation to support our work: