02Geek HTML5 and JavaScript, TypeScript, React, Flash, ActionScript online School
Previous VideoNext Video

005.003. Bubbling events in React

Tutorial: Bubbling Events in React

In this tutorial, we’ll dive into event bubbling and handling events in React, a crucial concept for building dynamic and efficient applications. By the end, you'll have a clear understanding of how to use callbacks for event handling and how to manage application state centrally.


1. Introduction to Event Handling in React

React handles events differently than traditional DOM-based JavaScript:

  • React does not use the native DOM event bubbling by default.
  • Events are handled through callbacks passed via props.
  • This allows greater control and makes the state and event propagation more predictable.

2. Structuring the Navigation Model

To make our navigation dynamic:

  • Create a Navigation Model:
    • Define an array containing the links and names for each menu item.
    • Example:
      const navModel = [
        { link: '#portfolio', name: 'Portfolio' },
        { link: '#about', name: 'About' },
        { link: '#contact', name: 'Contact' }
      ];
      
  • Pass this model to the Nav component as a prop for rendering.

3. Dynamic Rendering of Navigation Items

Instead of hardcoding the menu items:

  1. Loop Through the Navigation Model: Use Array.prototype.map() to iterate over the model and generate NavItem components dynamically.
    const navItems = navModel.map((item, index) => (
      <NavItem key={index} link={item.link} name={item.name} />
    ));
    
  2. Render the Items: Place the generated NavItem components in your Nav component:
    <ul>{navItems}</ul>
    

4. Capturing Events with Callbacks

To handle menu clicks:

  1. Add an onClick Callback in the Nav Component:

    function Nav({ data, onClick }) {
      return (
        <ul>
          {data.map((item, index) => (
            <NavItem key={index} {...item} onClick={onClick} />
          ))}
        </ul>
      );
    }
    
  2. Define the Callback in the Parent Component: In your App component or higher level:

    function handleLinkClick(event) {
      event.preventDefault(); // Prevents default anchor behavior
      console.log('Navigating to:', event.target.href);
    }
    

    Pass handleLinkClick as a prop to the Nav component.

  3. Pass Down to Individual Items: In the NavItem component, bind the click handler:

    function NavItem({ link, name, onClick }) {
      return (
        <li>
          <a href={link} onClick={onClick}>
            {name}
          </a>
        </li>
      );
    }
    

5. Binding Context with .bind()

React requires explicit binding for event handlers to ensure the this keyword points to the correct context:

  • In class components, bind the handler in the constructor:
    constructor(props) {
      super(props);
      this.handleLinkClick = this.handleLinkClick.bind(this);
    }
    
  • Alternatively, use arrow functions in modern React:
    onClick={(e) => handleLinkClick(e)}
    

6. Preventing Default Behavior

To stop the browser from navigating immediately:

  • Use event.preventDefault() in the click handler.
  • Example:
    function handleLinkClick(event) {
      event.preventDefault();
      console.log('Custom navigation logic here');
    }
    

7. Centralizing State Management

For large-scale applications:

  • Avoid placing state in every component.
  • Centralize state management in the top-level App component.
  • Use props to pass down state or state-modifying callbacks.

Example:

<App>
  <Nav data={navModel} onClick={handleLinkClick} />
</App>

Alternative Approaches in 2024

  • React Hooks:
    • Use useState and useEffect for managing state and side effects.
    • Replace class components with functional components for cleaner syntax.
  • React Context API:
    • Share state and handlers across deeply nested components without prop drilling.
  • State Management Libraries:
    • For larger applications, consider Redux or Recoil for centralizing state.

Conclusion

This tutorial covered:

  • React’s approach to event bubbling.
  • Creating dynamic navigation.
  • Centralizing state for better app scalability.

In the next lesson, we’ll merge the model with the view to create a cohesive dynamic system. Stay tuned! 🚀

Video Transcript

00:01So far we kind of avoided the topic of events and react
00:04because they're a little bit different than
00:06how you would work with it normally.
00:08But in this lecture we're gonna reveal
00:11how you would actually do these type of things.
00:13Inside of React.
00:14We're gonna talk about event bubbling
00:15and how do you bubble them?
00:17'cause you're manually going to BU events
00:19whenever you need them.
00:21We're gonna see how we do that through passing properties
00:24that have callbacks instead
00:25of triggering the standard JavaScript event bubbling
00:29that I'm sure you're familiar
00:30with from your work in general.
00:32So let's see it in action.
00:35Alright, we created a basic navigation,
00:37but I really want to move into a more dynamic world.
00:41And to do that I want to go ahead
00:42and create a model for our view, for our menu as well.
00:47So let's go ahead and just place this all the way up here.
00:50I'm gonna call this uh, nav.
00:52And for our nav itself, just for now, it's really nav model
00:56'cause we're probably gonna go back
00:57to it and change it again.
00:58But let's go ahead and figure out
01:00what will be the content within.
01:01So first of all, if we go into our nav, we have basically
01:05four items of content.
01:07We have four navigational items where one
01:09of the links is echoed twice.
01:11It's echoed also in that nav bar on the top with some copy.
01:15Sometimes it's with, sometimes it's without.
01:18So literally right now what it's what it is,
01:20what we have here is a link and a value.
01:23A link and a value is really the differentiator
01:25where this is something that the first item we could say is
01:28always uh, invisible.
01:29So in our data itself, what we really need,
01:31if we go into our client, we basically need a structure
01:34that's similar to link name just like we had previously.
01:37So if I go ahead here and just copy a couple of those.
01:40So we have a link and a value
01:42and I'm gonna go ahead into our link name combination
01:45and just assign the the correct value.
01:47So first of all, for our link, our first item is gonna be
01:49this HF that is right there.
01:53And if we go back into our navigation, we,
01:55that was our title.
01:58So let's just put that title where the name is.
02:01And let's literally just go through this flow
02:03and move by updating.
02:05We have portfolio and portfolio.
02:08Portfolio and portfolio.
02:12What else do we have here? We have about and about.
02:16It's about time that we have and about and about and about.
02:21And we are about done, right? Almost done.
02:23We have also contact. So let's go ahead and copy contact.
02:27Beautiful. So we created our model.
02:30Now that we have our model, let's just also link it
02:33to the models that are being sent.
02:34So I'm just gonna set this, I'll call this nav
02:37and I will send in our navigational model
02:42and let's go into our app now and send our nav items.
02:46So I'm just gonna go ahead here
02:47and send that data through into the nav data,
02:50which is gonna be our this props
02:56data nav.
02:58And let's go into our nav and structure it.
03:00So we'll actually work the way we expect it.
03:02So first of all, the first thing
03:04that we were gonna do is we're gonna link in
03:06that right default link, which is inside
03:09of our nav bar link.
03:10Now the best way for me to do this is probably
03:12to just strip out the first item.
03:14So I'm just gonna create here a
03:15lead and let's just call this.
03:17So let's just give it a name such as let's say first data
03:21and it's gonna be this props data position zero.
03:25Okay, so that's good and let's also copy all the rest.
03:28So let's call the rest. Let's just call it A for ra.
03:31Uh, 'cause it's just our data props data.
03:35And I'm just gonna go ahead
03:36and slice out everything from position one and onwards.
03:39Okay, so now that we have our data structure,
03:41let's first put in our first data point.
03:44And our first data point.
03:45We could literally just go ahead here
03:47and replace our content that we have here, uh,
03:51with our data structure, which was our first data
03:55name was for the name.
03:57And we had that link for the link itself.
04:00So first data link. Beautiful.
04:03Now for our first item, we kind of wanna keep it unique
04:06and different, so I'm just gonna keep it the way it is.
04:08But I'm just gonna send in our link itself instead
04:12of having it hardcoded here.
04:14And then this remains the same.
04:16Now for our nav items, what I want to do is I want
04:18to list them in dynamically.
04:20So to do that, what I would like to do is I want to cycle
04:23through our A that we have here
04:26and replace its content with content
04:28that would actually fit our rendering.
04:32So we already created really those nav items.
04:35So all I really need to do is loop through our A.
04:38So I'm gonna use a four each to do that.
04:40And I'm gonna send inside of it, uh, arrow function.
04:43So it's properties for each expect an element, an index
04:47and the array itself.
04:49So we got ourselves, our beautiful four uh, each.
04:53And in it we have our arrow function.
04:55It looks really weird but incredibly efficient.
04:57Okay, so what do we wanna do?
04:59We wanna go to the element
05:00and we really wanna replace it with
05:02what we wanna replace it with A nav items.
05:04If I go ahead here, let me just grab one of those nav items
05:07and just place it in there instead.
05:10But what I wanna do is instead of sending this content
05:13directly, I'm gonna use that.dot syntex
05:15that we saw previously and send inside that element.
05:18'cause it's gonna loop through item by item.
05:20Last but not least, I also wanna make sure
05:22that I set here a key that is unique.
05:24So to do that I'm gonna use that elements, uh,
05:27link, which is unique.
05:29So that would give me a unique element here for unique
05:31by the way, for this zone.
05:33So it doesn't have to be an ID that is unique
05:35for the whole application.
05:36It just needs to be unique in the structure in the
05:39current tree that you're at.
05:40Which in our case it would be no one would ever
05:42put two menu items.
05:44Well, in our situation, no one would.
05:46If not, we would have to create a link such
05:48as just putting here a number or something of the source.
05:50But this would work for us. By the way,
05:51our index is unique as well.
05:53So I could go ahead here
05:54and just set it to be our index that's unique.
05:57Okay, so it really doesn't matter the value itself
05:59as long as it is unique.
06:01Let's continue. So now that we've created it,
06:03all I really have to do is find where would I position it,
06:05which would be right after our hidden item.
06:07And then I could go ahead here and just delete all of that.
06:09And instead of that position,
06:11our array that we've just created.
06:13Now if everything worked according to plan,
06:15then we should re-render.
06:17But let's see, we have your small little problem.
06:20Uh, so first of all, we're getting here
06:22that our JSX is not closing well.
06:24So that I is not working for its needs.
06:28Um, so it needs to be quoted.
06:30Oh yeah, yeah, yeah, of course it needs to be quoted.
06:32If I go ahead here, I need to put that inside of brackets
06:35because if not, it's just I and doesn't really mean much.
06:39So, and there, there we go. Everything's working. Beautiful.
06:42Okay, so now that everything's working,
06:44I wanna move on into the next topic, which is events.
06:47Now in, in reality we don't want the links
06:49to actually re-render our application,
06:52but what we really want
06:53to happen is when the links are clicked on for us to capture
06:56that process and then do something with it.
06:59Now we don't want to create your callbacks inside
07:02of each nav element.
07:03It would really work much better
07:05for us if we could do it externally from here.
07:07So I'm gonna go ahead here
07:08and just create on link click
07:13and it's gonna be an event.
07:15And I'm gonna go ahead here
07:16and I'm just gonna,
07:17for right now I just wanna do a console log.
07:21Hello. Just get it to run.
07:23So what I'm gonna do on an R on click here,
07:26what I'm gonna do is in the navigational elements
07:29that I'm sending in, I'm gonna append OTA
07:31and on click and an on click.
07:33Our on click navigational element will basically bound
07:37inside of it are this on click.
07:40Now again, if we wanted our on click to work, we would want,
07:43we would need to bind it
07:44because we want keep reference
07:46to this when we're inside of here.
07:49To do that, we would want to go in our constructor just like
07:51we did in our portfolio, I believe
07:53where in our portfolio item we had your,
07:56we updated basically calling our constructor.
07:59So you know, let's just do it again inside
08:01of our nav calling our constructor creating one set.
08:04Once we created it, we have to call super
08:07and send our props in
08:08because we wanna make sure that our props continue to work
08:11and any element that we expect to be a callback,
08:14then we'll just go ahead here
08:16and set it to bind to itself, making sure
08:18that any time is called it will treat the this as the this
08:21that we want it to be treated at.
08:23As now on our on click event is going
08:26to be sent into our nav element.
08:29And one of the beauties are is because
08:32although we don't have your beauty, because we set all
08:35of our, our on click is basically gonna be captured here on
08:38our I itself, but it's not gonna be captured on our hre.
08:41So to make sure that it gets captured on our hre as well,
08:45we probably would want to also go inside of here
08:47and set here an on click
08:49and our on click by the way,
08:51I think it's lowercase, I'm not sure.
08:55Well let's set it uppercase then we'll see what happens.
08:57And on our on on click, I want to go ahead
08:59and send it to this props on click.
09:03Literally passing through our callback.
09:06So our callback is gonna be set inside of our nav item
09:09and then it's gonna capture it in our A.
09:11Now if everything works according to plan, if I save this
09:14and I go back to my app,
09:16whenever we click on a navigational element,
09:17we should see here an update with hello,
09:20which is exactly what's happening.
09:22Now the one thing that I want to do is I want to kill
09:24or stop this date default functionality
09:27that's happening right now
09:28because what I really want to want to happen is I want this
09:32to flow even further up the chain.
09:34So really I don't wanna control the navigation up here.
09:38Actually where I want to control it is all the way on the
09:40top, in the top on our application itself.
09:43So again, to do that, I'm just gonna go ahead
09:45and kind of, I'm just gonna go ahead
09:47and cut this out really for a second.
09:49Move it all the way into my app.
09:51And in my app itself I'll have an on link click
09:54or on nav on uh, you know what?
09:57On link click Why not On link. Link. On link link. Okay.
10:01So that if that's good
10:02and I accept that on link, link click, I need
10:06to send that on link.
10:07Click to our menu.
10:08So I'm gonna set here an on click
10:12and I'm gonna go ahead
10:14and again, remember that we have here a binding
10:17that is set automatically.
10:18So we will have a, this that relates
10:21to our full app whenever it's called.
10:22All I have to do in my nav is make sure that instead
10:25of having that callback that I had up there below
10:28that I'm sending the this dot props dot on click.
10:33So what I'm literally doing is I'm passing it along the
10:36line, making sure that it's continually continuing
10:39to implement that item.
10:40Now once I've done that, I'm gonna go into my app.
10:42And again, you could do this in many layers.
10:43And the reason why I'm doing this is
10:45because I don't really want my navigation to have a state.
10:48I don't want it to know what state it's at.
10:51While our application definitely needs to know it's stated,
10:54which is gonna be the next thing we're gonna be working on.
10:57So what I'm trying to do is I'm trying to move everything
10:59to the central place where the state will be able
11:02to control both how the navigation would look like,
11:05but also what elements will be rendered.
11:07'cause we don't want portfolio about inContact rendered.
11:10We want them to dynamically render based on
11:13where we clicked on or where we are currently inside.
11:17So with that said, let's just make sure
11:18that everything is working and I'm gonna go ahead here into
11:20my on click link area
11:23and I'm just gonna ask the default to not happen.
11:26So e dot prevent default.
11:30Now if everything worked according to our uh, hopeful plan,
11:35our prevent default, what should do is basically
11:37whenever it's gonna be clicked on, it should
11:39basically not do anything.
11:40So if we're right now we're in the portfolio
11:43and I click into about, then we should see the hello
11:46but it shouldn't jump beautiful, which is exactly
11:48what we wanted it to do.
11:50And generally speaking, what we've just done right now
11:52Is exactly the way you wanna work when you're
11:55working with your components.
11:56Don't have states for every single component,
11:59but instead of that, try to find
12:00where is the most logical place for the state to happen.
12:04In our case, the navigation,
12:06although changing really is going to affect
12:08what is gonna happen within all of the application.
12:11So the state that really needs to change is something
12:14that's happening within our application
12:16that then could re-render our navigation based on
12:19that change and re-render all the other remaining items.
12:23Okay. If that makes sense.
12:24So we'll continue in the next lecture
12:26and don't worry, it makes a lot
12:27of sense once you'll see it all connected.
12:29In this lecture we really were introduced to
12:32how you're most efficiently working with events in React.
12:36And again, react is all about making things
12:38transparent and obvious.
12:40And same is true with the bubbling of events.
12:43In the next lecture we're gonna merge our model
12:46with our view to make it easier for us
12:49to create dynamic views.
12:51Basically redefining what's gonna actually sit inside
12:54of our client mimicking.
12:55In many ways the business logic.

Ready to Level Up Your Skills?

Join thousands of learners on 02GEEK and start your journey to becoming a coding expert today!

Enroll Now for Free!