How to Build a Details Components for Quick Links
Welcome back to the course. In this video, we're going to add in the quick links. Let's go ahead and make a component so that we can use this throughout our application.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

You'll notice that we can use it in a lot of different places. If you cycle through the app, you'll see that the password requirement has it. There are a few different places that contain it. Order summary has it. They're slightly different so we'll probably customize the bit as we go on, but we want to make that component.

Let's close out this, let's go into the components folder, and let's create a new file. Let's call it details.js. The let's say:

details.js

import React, { Component } from 'react';

class Details extends Component {
    render() {
        return (
            <div className='details'>

            </div>
        )
    }
}

export default Details;

Now, let's look at our design. We have this title, we have a little border, and then we have a few items in there. What we want to do is provide a title and some links. So let's say:

details.js

class Details extends Component {
    render() {
        const { title, links, onClick } = this.props;
        return (
            <div className='details'>
                <div className='details__title'>{title}</div>
                <div className='details__links'>
                    {
                        links.map(link => {
                            return <a onClick={onClick} className='details__link'>{link.title}</a>
                        })
                    }
                </div>
            </div>
        )
    }
}

Read that all over. If I was going a bit fast, just either pause it or type it all out as I'm talking right now. We got details, title, links, and they mapped over it. We got an onClick and details__link. Let's go ahead and use this component and then style it.

Let's go into signinForm.js, and at the bottom here let's say Details. Notice I'm using the auto-import. Make sure at the top here you import Details from '../details'.

large

Now, what we want to do is use it and provide it some props. We want to say:

signinForm.js

    <Field className='sign-in-form__login'
    onClick={() => console.log('tryna submit')}
    type='submit'
    title='Login'
    name='login'
    component={FormButton}/>
    <Details className='sign-in-form__details' title='QuickLinks' links={}/>
</form>

Let's get that in, then scroll up here, and let's say:

signinForm.js

render() {
    const { className, handleSubmit } = this.props;
    const links = [
        {
            title: 'hey there',
            onClick: () => console.log('heythere')
        }
    ]

Type out this array with this one object in there, and then let's go down here and pass it into links.

signinForm.js

    component={FormButton}/>
    <Details className='sign-in-form__details' title='QuickLinks' links={links}/>
</form>

Now, one thing we need to change our details, so let's go into detail.js, is we need to say link.onClick because we want a different onClick for each one of these. We don't want one onClick for every link. We don't want an onClick that does the same thing for everything.

details.js

class Details extends Component {
    render() {
        const { title, links } = this.props;
        return (
            <div className='details'>
                <div className='details__title'>{title}</div>
                <div className='details__links'>
                    {
                        links.map(link => {
                            return <a onClick={link.onClick} className='details__link'>{link.title}</a>
                        })
                    }
                </div>
            </div>
        )
    }
}

We want a specific onClick for each link. That's going to be in the object we provided. If you go back to signinForm.js. You'll see that we provide that onClick in the object here. It's taken its title in onClick in there.

We're passing that object or all of those objects, there's going to be more than one, into Details. Then Details is going to map over that object links and it's going to return an a tag for each link and give it the onClick and the title of that object.

In this case, there's one object, but there's going to be a few when we get done. Let's try it out. You'll see that we have QuickLinks, we have Hey there, let's inspect the element, and see what happens when you click Hey there.

It doesn't really look like a button, but if you click it you'll see in a console says Hey there five times. Each time you click it, it increments it a bit. That's what we want. Now, we have to get rid of this error. It says Each child in an array or iterator should have a unique "key" prop.

large

This is pretty simple, we've done this quite a few times. All we have to do is say:

details.js

class Details extends Component {
    render() {
        const { title, links } = this.props;
        return (
            <div className='details'>
                <div className='details__title'>{title}</div>
                <div className='details__links'>
                    {
                        links.map((link,index) => {
                            return <a key={index} onClick={link.onClick} className='details__link'>{link.title}</a>
                        })
                    }
                </div>
            </div>
        )
    }
}

This will work. See the error goes away. Now, when you're working with JSON, you're typically going to be receiving a number of items back from a server. In this case, we're never going to be receiving different items back for this object because it's just not something we really need to put on the back-end.

We don't need to put these QuickLinks on the back-end, although, if you wanted to easily change these, and not have to redeploy your entire application, if you just want to quickly change it, then you might make a dashboard for an admin to say hey I want to change the Quicklinks on the admin page.

Then you could just edit these values and hit an endpoint. Then it would fetch this from a database and then repopulate it. Now, the reason I'm talking about this is because instead of using an index we can just use an ID because in Mongo your database objects in a collection are each going to have their own unique ID.

So we're just going to assume that this has an ID. We're gonna assume we're using it from the back-end. Let's go in to signinForm.js, and let's provide an ID in each one of these objects. Let's say:

signinForm.js

render() {
    const { className, handleSubmit } = this.props;
    const links = [
        {
            _id: 0,
            title: 'hey there',
            onClick: () => console.log('heythere')
        }
    ]

That will work as well. The key worked. That works.

large

Let's go ahead and add in the rest of these items, and then get it styled. So instead of Hey there let's say:

signinForm.js

render() {
    const { className, handleSubmit } = this.props;
    const links = [
        {
            _id: 0,
            title: 'Not Registered? Create account here',
            onClick: () => console.log('heythere')
        }
    ]

Now, I just want to verify what that looks like. Create Account here. We still need forgot account email and forgot password. I'm just going to copy this object a few times, and let's change the IDs.

signinForm.js

render() {
    const { className, handleSubmit } = this.props;
    const links = [
        {
            _id: 0,
            title: 'Not registered? Create account here',
            onClick: () => console.log('heythere')
        },
        {
            _id: 1,
            title: 'Forgot account email?',
            onClick: () => console.log('forgot email')
        },
        {
            _id: 2,
            title: 'Forgot password?',
            onClick: () => console.log('forgot password')
        }
    ]

Now the design doesn't have anything for forgot password, and same with the account email. We're not going to build that out, but we're going to be building our create an account form, the sign up form.
We want to push this to a different location, so let's just check to see if this is working, and then we'll import history and push the user when they click this button.

Let's go into Chrome. You'll see we have our items here now. You can click on it to have it console log it's onClick.

large

What we want to do when they hit not registered is we want to push them to the signup route. If you remember in bootstrap.js, we have this route called Signup. We're want to push them here and push them to the Signup component.

Let's go ahead and get rid of this console.log and let's say:

signinForm.js

render() {
    const { className, handleSubmit } = this.props;
    const links = [
        {
            _id: 0,
            title: 'Not registered? Create account here',
            onClick: () => history.push('/signup')
        },

Now, what we need to do is we need to import history. Let's say import history from '../../history'. If you remember what this is, it's an object we created in our root source directory. We passed it into our bootstrap.js into our router, so we're dealing with the same history.

When we click on this button it's going to push us to sign up. Let's try it out. Click not registered, it pushes us up to sign up. That works. All we need to do now is style it and place it on the grid.

large

Let's commit our code and handle that in the next video since this is going on for a while. Let's go to our code and commit it. Let's say:

Terminal

git status
git add .
git commit -m "built the details component for quicklinks"

I'll see you in the next video.

Resources