Configuring Dropzone for Blog Featured Image
Up until this point, if we wanted to upload a featured image for our blog, we had to go through DevCamp Space. So in this guide, we're gonna start the process of adding our dropzone image component so that we can start adding images directly to our blog.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

Now in this guide, we are simply going to bring in the component and we're gonna add those three configuration functions that need to be there in order for this to work. Everything we're gonna be doing in this guide is reinforcement learning, we've already implemented all of this for the portfolio manager, and we did it three times. In this case, we're only gonna use a single image uploader 'cause we only have one item that we wanna upload.

So we're gonna take it nice and slow, but we are gonna move maybe a little bit faster than we did in the last one because you've already done this and, hopefully, it'll just be a good refresher for helping you understand all of the items that are necessary and if it was fuzzy before, maybe the second time through, it'll start to make sense what each one of these functions do.

So let's start by opening up Visual Studio Code, and, at the very top, let's add our dropzone component. So we're gonna import DropzoneComponent from react-dropzone-component just like that,

blog-form.js

import React, { Component } from "react";
import axios from "axios";
import DropzoneComponent from "react-dropzone-component";

import RichTextEditor from "../forms/rich-text-editor"; 

and now we need to bind our three functions, our three configuration functions, and we're gonna follow the same naming convention that is in the React dropzone component documentation and also that we followed in the earlier guides. So the very first one is gonna be called componentConfig and so I'm gonna bind that to this.

So I'll say this.componentConfig equals this.componentConfig.bind(this) and now let's go and let's do the same thing for the, if you remember, it's the djsConfig, it's just another dropzone config, so I'm gonna this.djsConfig equals this.djsConfig.bind, if I can spell it correctly, this, and then lastly is our function that we'll run whenever a user has dropped a image into the dropzone component or if you click and add it through the file system. So that one I'm gonna call this.handleFeaturedImagedDrop equals this.handleFeaturedImageDrop.bind and pass in this.

this.conponentConfig = this.componentConfig.bind(this);
this.djsConfig = this.djsConfig.bind(this);
this.handleFeaturedImageDrop = this.handleFeaturedImageDrop.bind(this);

Okay, with those three implemented and bound to this, now we actually need to implement the functions themselves. Now definitely you can feel free to reference the portfolio manager form, that's what I did when I was building this out. Never feel bad about looking back at your previous code. Part of the reason why you use tools like GitHub is so that you can have your own set of examples of code that you've built in the past.

I'd say a significant portion of my day when I'm developing applications is spent with me going through old projects and seeing how I've implemented certain features. Part of the reason why you spend a lot of time upfront learning about how to build something new is so that you can build it more efficiently the next time you have to do it because you already have a point of reference.

So what we're gonna be doing here is pretty much mimicking what we did in that portfolio form. So componentConfig doesn't take any arguments, none of these functions are gonna take any arguments, and we'll say return and then the very first set, the first item is we have to list out the items, the types of files we want to allow.

So that's gonna be called iconFiletypes and that's gonna be an array of strings, not a object of strings, an array of strings, and that's gonna be jpg and then .png.

Now to be clear, this is not to define the validations or anything. So this doesn't say that only a jpg or only a png is gonna be allowed, this is more for the label so that it shows you the icons that are allowable or the file types that are allowable. And then we have the flag and we say showFiletypeIcon and we want this to be true, and then lastly, the postUrl.

Remember that this is our kind of mocked image URL so this is a URL that when we drop a file, it will mimic like it's being sent and that's what gives us the cool little animation where it adds the check mark if the file is valid and it's something you can upload. And that's gonna be a string and we'll say https://httpbin.org/post.

blog-forms.js

componentConfig() {
  return {
    iconFiletypes: [".jpg", ".png"]
    showFiletypeIcon: true,
    postUrl: "https://httpbin.org/post"
  }
}

Okay, so that is all that we need there and now let's move on to the djsConfig. So I'm gonna say djsConfig, no arguments, and inside of here, we are also returning an object just like in the component config. And in this one, we are saying, if we want to have add or remove links and also how many files we're allowing.

So for this, I'm gonna say addRemoveLinks, this gives us the ability to have a little link in there that will say yes, I want to add a file and once it gets added, if a user wants to remove it, then they can just click that little X and it will be removed. So I wanna say yes, I do want that and then maxFiles is going to be one.

Okay, those are our first two. Those really are based around the functionality of the component itself. Now we're going to talk about behavior, what happens when a user drops a file or picks one out from the file system. So let's take our handleFeaturedImageDrop function here and once again it takes no arguments and for this one, it's going to return a single object with the function of addedFile and here this is gonna be a fat arrow function where it takes in that file and then it's gonna say this dot and in this case we're gonna want it to setState.

And we haven't created that state yet but we can just mock it right now so I can say this.setState and in this case, I'm gonna say featured_image and then pass in the file. And just for the sake of so that we don't forget anything later on, let's just add this featured image up into the start of our base state. And we'll just have it start blank, so featured_image and that is all that we need to do on the configuration side. Now we can actually add the component.

So if you scroll all the way down, below your one column div here, below the rich text editor, let's create a wrapper div and let's check our portfolio form, I'm gonna look at that portfolio form component to see if we added a class there or not. So I'm gonna scroll all the way down to see each one of our image uploaders and yes, so we have a image uploader here and then if you scroll down, I'm trying to see if we had any other wrapper and no, we did not.

So it's just a class name of image-uploaders and then we can choose later on if we want to shrink it down or apply some more specific styles. But for right now, let me just copy this image-uploaders className and this div, make sure you close it out, and now this is where we're gonna call our dropzone component.

So DropzoneComponent just like that and the props that this is going to take is gonna be, it's config, so we're gonna say the config is this.componentConfig and this is a function we want to run right away, so because of that, we are going to add our parens. Remember, you've seen both sides of this and this can be something that is very confusing to a new developer with React is you see certain times we pass a function as a prop and we do not include the parens.

And so, I know I've kinda talked about this a few times but this is something I've had so many questions about that I think it's worth it to go into a little more detail on it.

The key difference on when you wanna use parens versus when you don't when you pass a function as a prop is that if you want the function to run right away, then you add parens. In this case, we want the DropzoneComponent to know about its configuration right away, immediately. So because of that, we want to call the function, whenever you want to invoke a function, you add the parens.

Now other times such as say the logged in portion that we sent to auth or one of those handler functions, we want those to be triggered later on at some other point. So for example, our logged in function or auth function, we want it to wait until the user had actually signed in before we fire that and that's the reason why when we pass that function as a prop, we didn't call it right away. We simply were handing it over to that child component and say whenever you wanna use this, you call it, we're not gonna call it right away. That's what the key difference is.

So the first prop is config, the next one is going to be the djsConfig and that's gonna be equal to this.djsConfig and once again we want that one invoked right away and then lastly is gonna be our handler. So eventHandlers and the reason why it's eventHandlers is because if you look at the documentation, we are using the, if I can find it and scroll all the way up, so we're using the addedfile eventHandler but if you look at the documentation, there are actually a wide list of eventHandlers that you can work with with dropzone. So that's the reason why that's plural, because you can pass multiples if you need to.

So eventHandlers is gonna be equal to this.handleFeaturedImageDrop, once again, we do want that one to fire right away. And then that is all that we need in our DropzoneComponent. We also as a child prop, not a prop, but as a child component, we wanna pass in a className so that we can give a label. If you remember we also did that for the portfolio manager form. So here I'm gonna give a div with a className and this one has to be exactly like this of dz, short for dropzone, message, and then inside of this div, I'm gonna say Featured Image.

And that's going to be our label, note that this is a child element being passed into DropzoneComponent. So you close off the start of the tag and then you add this div as a child element and then you close off the entire component.

blog-form.js

<div className="image-uploaders">
  <DropzoneComponent
    config={this.componentConfig()}
    djsConfig={this.djsConfig()}
    eventHandlers={this.handleFeaturedImageDrop()}
  >
    <div className="dz-message">Featured Image</div>
  </DropzoneComponent>
</div>

So hit save here and then let's come back here and hit refresh to make sure you're working with the latest version. Click on the New Item, you can see that our featured image here is working nicely.

large

Let me switch to Finder and grab a sample image, so you can grab any image, any jpg or png on your computer. Click and drag it and it looks like everything is working nicely. So great job if you went through that, you now have implemented dropzone into another piece of your application and hopefully you can start to see a little bit of why people love tools like React and component-based architecture.

Because, in just about 10 or 15 minutes, we were able to take a pretty significant piece of technology with being able to have a dropzone element where users can click and drag files into your application and we're able to do that by just calling a component, passing in a list of configuration items, and now it's rendering on the screen.

So great job if you went through that. In the next guide, we're gonna wire up our DropzoneComponent into the blog form.

Resources