- Read Tutorial
- Watch Guide Video
So the goal by the end of this guide is to be able to click on our Open Modal link, to be able to create a guide by using the form, and then when we hit save I want the form to clear out, I want the modal to close, and I want that new blog post to be placed at the very top of the page.
Now in order to do this, we're gonna have to do something we've not done before, which is to traverse three components and to pass data between those. We've done something very similar when we had our parent portfolio manager class and then the portfolio manager form pass data when the portfolio was created, and then we passed the data to the sidebar.
What we're going to do now is slightly different, we are going to start at the blog form level. From there, once that's successful, once that is submitted successfully, we are going to communicate with the parent, which is the modal, and then we are going to also communicate with its parent.
So the term is the grandparent component of our blog form. Now I will say that this is absolutely the most data flow that you're ever gonna want to do with passing props. You do not want to go beyond these levels, you don't want to pass the data up the chain more than twice. I can promise you even doing it twice can be a little bit tricky and can be a little bit buggy.
And this is where you start to get into the realm of using tools like redux and other things like that that we'll discuss in the future, can be helpful because the further you have to pass data up the chain, or down the chain of components, the more complex it can be and also the trickier it can be if you ever try to change any of that data.
What we're doing here is perfectly fine because, as you're gonna see, it is a pretty simple workflow. In fact, the middle component, our modal component, is literally going to do nothing with the data except pass it straight up to the blog component.
So I know the explanation there might be a little bit tricky. So don't, if it feels fuzzy, do not worry about it, we're going to get into the code, and hopefully by the end of it, everything will make sense.
So let's get started, the very first thing that I talked about wanting to do is to clear out the form when we hit submit, or when we hit save and it is created successfully. If you come to Visual Studio Code and go to the blog form you can see that we have our base state of title and blog_status.
Well, inside of our handleSubmit then response, in order to clear the form out, all we have to do is call this.setState, and then inside of setState we are going to go and, we're going to click title and pass in an empty string and then blog_status and pass in an empty string there.
blog-form.js
.then(response => { this.props.handleSuccessfullFormSubmission(response.data); this.setState({ title: "", blog_status: "" }); })
So what that's going to do is we're gonna get a response back, this means that it was successful. It's gonna create the record and then we're going to take our title and our blog status form elements, and we're going to clear them out. Now the reason why we're able to do this is if you scroll down to the form itself, remember that our value is being pulled directly from our state value.
That's why this is so powerful because, both for our records for blog_status and for title they have this direct communication line with state, which means we're able to update their values any time that we want, which is very helpful, especially in cases like this. So now that we have that, in the last guide we already communicated with our parent component.
So when we say this.props.handleSuccessfulFormSubmission, and we're passing in response.data, what we're doing here is we're passing that to the blog-modal. Now response.data doesn't give us everything we need, in order to do that I'm also going to add in the portfolio_blog.
This way, the blog-modal doesn't have to try to parse the data, we are sending the actual blog record, not the response data. And if you want some clarification on that, simply console log out response data and you'll see you still have to go one level further in order to get to that portfolio blog.
I would rather do it right here in our blog form so that the blog-modal literally does nothing except take a blog and pass it up to its parent component. So now that we have that, let's go into the blog-modal. And we're going to look at our handleSuccessfulFormSubmission function here.
Now I'm gonna get rid of the console.log statement, and I'm going to prematurely create our function for the blog. So I'm gonna say this.props. and we can call this anything we want. We can say handleSuccessful, instead of form submission, let's say NewBlogSubmission, and then we're going to pass in that blog record.
blog-modal.js
handleSuccessfullFormSubmission(blog) {
this.props.handleSuccessfulNewBlogSubmission(blog);
}
This blog record's the same one that we're getting from the blog form. Now we've not created this method inside of the blog component yet, but we can just copy this, go into our blog, and inside of our constructor make sure to bind the method to this because we're gonna be passing this as a prop.
So this.handleSuccessfulNewBlogSubmission, that's a mouthful, equals this.handleSuccessfulNewBlogSubmission.bind, and pass in this, and then lastly let's create this method. This is going to expect a blog, and here inside of it, we have a couple of tasks to do.
blog.js
this.getBlogItems = this.getBlogItems.bind(this); this.onScroll = this.onScroll.bind(this); window.addEventListener("scroll", this.onScroll, false); this.handleNewBlogClick = this.handleNewBlogClick.bind(this); this.handleModalClose = this.handleModalClose.bind(this); this.handleSuccessfulNewBlogSubmission = this.handleSuccessfulNewBlogSubmission.bind( this ); }
Remember that we want to close the modal out? Well we know how to do that because we have handleModalClose, and we have handle, and let's see ModalClose, and then we have the open one somewhere. So let's see, handleModalClose, oh yeah, handleNewBlogClick, that's what opens it up. So we already know we can do this, and there's a couple ways that you could close the modal out.
You could say this. and then handleModalClose, and this would close it for us and that would be perfectly fine. But because we're gonna update another piece of state, I'm just gonna say this.setState, and we're going to call blogModalIsOpen, set that to false, and then remember the second task we wanna do is to take that blog record and then pass that directly into our list of our blogs.
So remember we have this list of blog items right here, and so what we want to do is to place this record at the very top of that list. Now the easiest way to do this, I'm gonna call this blogItems, so we're gonna set state here. Now the easiest way to do this is to actually create an array and have it as a single item array with the blog inside of it.
So here I'm going to create an array with the brackets, I'm going to pass the blog in, this is the same blog we got from the modal and then from there I'm going to concat the current list of items. So here I can say concat and this.state.blog items, and that's all we need to do.
blog.js
handleSuccessfulNewBlogSubmission(blog) { this.setState({ blogModalIsOpen: false, blogItems: [blog].concat(this.state.blogItems) }); } handleModalClose() { this.setState({ blogModalIsOpen: false }); }
Now if this is a little bit confusing, let's take a quick look before we even test this out. Let's take a quick look at the JavaScript console, and I'm gonna show you exactly what we're doing here.
So let's imagine that we have this list of items. So I'm gonna say const items and say one, two, three. And say that we want to have some new record, some new item that we want to place here at the very front of our items array. Well, what we can do is we can add that item.
So I'm gonna say const first, and set it equal to say zero. It could be any number though, this is all just for an example. So I have this first record now, and I'm gonna say const newList equals first, and notice how I placed first inside of its own array. Whenever we use the brackets this is just creating a new array, so I'm saying first.concat items.
Now if we look at the new list, notice that we have our new array right here, and zero is at the very front.
So that is exactly what we're doing with our list of blog records. We're taking the current list and we're saying, hey, we want to slide this new record inside of it, but the way we're gonna do it is we're gonna create a brand new array, we're gonna place that blog into it, and then we're gonna add the other array and combine the two.
So let's hit refresh and let's see if everything is working. So it's taking a moment to load, it's all up now. Click Open Modal, say Full workflow test, blog status, let's say published this time, and then click save and let's see if this works. And it looks like we may have an error. Let's open up the JavaScript console, and yes we do.
handleSubmit for blog error, this.props.handleSuccessfulNewBlogSubmission is not a function. I know exactly what I did, handleSuccessfulNewBlogSubmission needs to be passed to the blog-modal. So let's come down to our BlogModal, I forgot to pass this as a prop. So handleSuccessfulNewBlogSubmission, and then pass in this. and then the full method name.
blog.js
return ( <div className="blog-container"> <BlogModal handleSuccessfulNewBlogSubmission={ this.handleSuccessfulNewBlogSubmission } handleModalClose={this.handleModalClose} modalIsOpen={this.state.blogModalIsOpen} />
Now, this is the reason why I keep these errors and these little bugs inside of the application. Anytime that you would see something like this, this is an error you will see whenever you see something where it says this.props.handle, whatever the name of your prop is is not a function.
The very first thing that that should tell you is not that it's not a function, but that it's not a function that the component knows about. And if it doesn't know about it it's probably because we didn't tell it about it, we didn't pass it in as a prop. So whenever you're passing in a function as a prop and you get an error like this, make sure you go back and verify you're actually sending it, so let's hit refresh.
That did create the record, notice that it did create the record, because the record creation process occurred at the blog form level, it simply didn't do the rest of what we're looking for. So now let's test it out again and I'll say another test, and this one will be a draft status. Hit save, and look at that, everything is working. You can hit refresh to make sure it actually is there, and it is.
So let's do a quick review, 'cause that was a decent amount of code. And so let's make sure we understand what's going on here. We have a blog-form component, this is nested inside of a modal component, which is nested inside of a blog component.
In order to be able to pass data from the blog-form all the way up to the parent blog, or I should say the grandparent blog, what we did was we created a function that we passed as a prop so that we could communicate with the modal. That entire function's job is to do nothing except to take the data from the API response and then pass it up to its parent, and then that parent is what did all of the work.
It performed the task of closing the modal, it allowed us to populate the list of vlogs, and all of those kinds of things. So hopefully that made sense. If it didn't, don't worry, because I will tell you that working with multiple components like this can be one of the trickier parts of React.
If this is still feeling a little bit fuzzy, if you're a little bit unsure of what's going on, do not even go any further in the course, work through this code. First, make sure it's working and then go through and watch this again. Read through the guide, make sure that you completely understand this full workflow.
Because if you understand this set of processes you're gonna be able to build a lot of React functionality. Because what we're doing here has to deal with state management, has to deal with updating data in multiple components, an entire application, and working with outside components like the React modal with Axios, with an outside API, and it's wiring all of that up together so that it works exactly like the way that you'd expect. So definitely make sure that this starts to solidify in your mind.
You don't have to feel like you're an absolute expert in it or anything like that yet. But definitely make sure that you have a high-level understanding of what's going on here, and then we can move on and in the next few guides, because we've been pretty technical for a while, in the next few guides let's take a little bit of a break and let's add some design elements to the app.