Adding a Callback Prop to Handle Tab Clicks
All right welcome back. Let's go ahead and actually render the correct content based on which one of these were clicking.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So just to show you in the design if we click newsletter we want to show something here

large

and if we click requests we want to show something different.

large

So obviously we're going to be developing these components later on, especially because they contain a ton of other components. But the idea I want to get across here is how to render different content based on the selected one.

So we're going to add in the functionality, let's go into our tabnav.js and let's actually go into our dashboard.js. So basically what we want to do is say hey let's take these values and throw them in tabnav and whatever one's true we want to display its component.

Now neither of them are true, so by default we want this Newsletter to be true. We want newsletter to be the first one by default to show up. So let's go ahead and display this component now because this one is true. Let's go to our tabnav and what we want to do is basically get rid of this content here and put a return and then we want to map over everything again.

So let's go ahead and copy this and put it in here and let's say instead of just returning all the titles let's get rid of that and say if tab.active then return tab.component. Make sure that's a lower case c. So you'll see that we have our tab and we're returning the title in this one and then we're saying hey if it's active return the component over here. Let's give this a class name of div tab-nav component.

tabnav.js

import React, { Component } from 'react';

class TabNav extends Component {
  render() {
    return (
        <div className='tab-nav'>
            <div className='tab-nav__tabs'>
            {
                this.props.tabs.map((tab, index) => {
                    return <a className='tab-nav__tab'>{tab.title}</a>
                })
            }
            </div>
            <div className='tab-nav__componet'>
            {
                this.props.tabs.map((tab, index) => {
                    if(tab.active) {
                        return tab.component
                    }
                })
            }
            </div>
        </div>
    )
  }
}

export default TabNav;

Okay, let's check it out in the browser, we should only see the component that says hey there newsletter, so login and you'll see it says hey there - Newsletter.

large

Now we don't really have the ability to switch between these. So what we have to do is create a function that will allow us to change whichever one we click on. OK so let's go in here and let's look at this, we have an a tag here so we want to say hey if we clicked on this one we want to switch whatever object belongs to this title.

Or whatever this title belongs to, or whatever object the title belongs to. So let's go ahead and say onClick is equal to a function. Now we're going to have to somehow change the data in dashboard because if we just change the data in tabnav it's not really going to be rendered and give us the right content because we're getting our props from dashboard. So we have to write the function in here.

Let's go ahead and say handleTabChange and let's make it an arrow function. And then in here we just want to map over our state here and then switch the selected one to be true. So the way we can determine which one we want to switch is by passing in this title from tabnav so we want to say onClick, let's run a function and let's pass into that function a call to a function that we've passed in with our props.

So let's say this.props.handleTabChange or whatever we call it in here. It doesn't matter, it can be a different one. But basically what we're going to have to do is call that and pass in the title so let's say tab.title. Now let's go provide this tabnav with a prop called handleTabChange and then we'll call this handleTabChange.

Now once we get it working this TabNav in dashboard.js I'm going to have us rename this handleTabChange function because it has nothing to do with this function in dashboard.js but they have the same name, so I want you to understand that they're for two different functions.

Okay so TabNav we're going to say handleTabChange equal to an arrow function that excepts a title and then we're going to say this.handleTabChange and pass in a title. So we're going to have to pass in a title right here, were gonna have to except a title and then what we can do is console.log clicked on tab and put a comma then say title.

Cool, so that should work and then we're going to change the name of the function after we see that it's working. Open it up I'm going to open up chrome since we're not using grid. We're going to login, I'm going to open the console and it should be logging whichever one we click. It looks like we have an error but that doesn't really matter, we'll handle that in a second, it shouldn't ruin anything.

Okay, so let's click on tab newsletter and tab requests so cool that works great. What we want to do now is switch the value of all the properties to false except for the one we clicked on okay.

So before we do that let me just show you how this naming works. So you understand that handleTabChange isn't the same function everywhere. So I'm gonna rename this prop to handleClick and then it's not going to work anymore because in tabnav we're trying to say this.props.handleTabChange so we have to say handle click.

So this function is directly referencing this function that we're passing in this title function on line 33 in our dashboard.js contains this. This is an arrow function that calls another function that exists in our dashboard.js alright. So just understand that this prop is not this function. It's just another function that's calling that function right here.

So let's just leave it as handleClick we don't really need to change that. And let's get rid of this error that we're getting when we see this.

large

Okay, this says it should have a unique key prop. The reason this is happening is because we're mapping over these arrays except for we're just returning things and we're not really returning a key with it, so on the a tag here we have to say key is equal to index. Now it's probably going to require that we do this in our other this.props statement as well.

But let's just try this out because we only got one error, okay so lets login or first let's reload our page so we get rid of the error that exists and let's login you'll see we still get it and that's because we're doing it here. We're mapping over it here in our other this.props.tabs.map so what we can do is either wrap this with another div and put a key in here except that's going to cause some problems with our grid when we want to put this on a grid.

So what I want to do instead is straight up just take this div and put it in here and then obviously we're going out to remove this return and put braces around this because it's now JSX. So now what we have to do is return this JSX. So let me just put this on a new line and give us an extra line down here. And then let's say return and then wrap it in some parentheses.

tabnav.js

this.props.tabs.map((tab, index) => {
    if(tab.active) {
    return (
        <div className='tab-nav__component'>
            {tab.component}
        </div>
    )
    }
})

Okay cool, that should work. I'm going to tab it over and that should be good. Let's check it out in the browser. Let's login and you'll see we're not getting that error anymore but we're getting it there, oK so let's see why is happening. And the reason that it's happening it's because we didn't actually apply the key to the div. So let's say key is equal to index and now we won't see it.

tabnav.js

this.props.tabs.map((tab, index) => {
    if(tab.active) {
    return (
            <div key={index} className='tab-nav__component'>
                {tab.component}
            </div>
        )
    }
})

All right, I'm sure a lot of you caught that before we even reloaded the page saying "Hey you didn't put in the index" that's why we're still getting that. So that gets rid of that error. And now we just need to actually switch between these and display a different component.

So let's just go ahead and do that in the next video since it's pretty long already.

Terminal

git status 
git add .
git commit -m "added callback to tabnav to handle clicking a tab"

Resources

Source code