- Read Tutorial
- Watch Guide Video
We know how to build three of those features into an application, now it's time to go to the final one which is the U, which stands for update. That means we're gonna be able to update records, so now, if we need to make a change to one of these portfolio items, we should be able to have a link here where we can click on that button, it should populate the entire form here, and then we can make our changes and then have the same type of workflow we had before when we were creating new ones where we can click save and it auto-updates everything on the page.
So we're not gonna do all of that in one guide, we're gonna break it into a few and you're gonna see we're gonna have to refactor our portfolio manager and form to get this to work properly with both the create and the update features, but you're gonna learn quite a bit about react along the way, which is the goal.
Let's get started, in this guide, what I wanna do is build out a link here on the sidebar. I want to have it listen for a click event, and then I want it to update the record inside of the portfolio manager. That's what we're gonna get accomplished in this guide.
Let's open up visual studio code here. We're gonna get started by adding a new item in state. So this is gonna be an object, so I'm gonna call this portfolio to edit, and then it's gonna start as an empty object, and so anytime that we want to edit an item, we are going to update state and replace this empty object with the portfolio record that we want to update.
Now that we have that in state, the next thing that we need to do is create a function that we are going to pass to the sidebar to listen for that click event. So here, I'm gonna say this.handleEditClick, and we're gonna bind it to this, so I'll say this.handleEditClick.bind to this, and then from there let's create the function itself.
It's going to handle the edit click, and it's gonna take in a portfolio item, 'cause remember, this is what we're going to replace, and we're gonna update state with. So here, I can say this.setState, and then inside of here, we're going to take this portfolio to edit record. So we're gonna take that portfolio to edit and I'm simply going to update it with the portfolio item.
portfolio-manager.js
this.handleFormSumissionError = this.handleFormSumissionError.bind(this); this.handleDeleteClick = this.handleDeleteClick.bind(this); this.handleEditClick = this.handleEditClick.bind(this); } handleEditClick(portfolioItem) { this.setState({ portfolioToEdit: portfolioItem }) }
So this is following a very similar pattern to what we've done throughout this course. We are going to update state, we're passing in via props this handleEditClick in the sidebar. When it gets called, which means when a user clicks edit, it is going to pass in the full portfolio item record and then it's gonna update the parent state here in the portfolio manager, so that's all we need to do here.
Now we need to pass this function directly into the component. So scrolling all the way down to the portfolio sidebar list. I'm gonna say handleEditClick equals this.handleEditClick, and we're not passing anything in, we're simply letting the PortfolioSidebarList component know that it now has access to this function via props.
portfolio-manager.js
<div className="right-column"> <PortfolioSidebarList handleDeleteClick={this.handleDeleteClick} data={this.state.portfolioItems} handleEditClick={this.handleEditClick} /> </div>
So I'm just gonna copy that. Now let's open up the sidebar list component and now what we need to do is add this as a link, so we already have a model we can follow here with the delete function, so we're gonna be able to do something very similar here for the edit.
In fact, what I'm gonna do in order to have both of these items sitting right next to each other, I'm gonna wrap them inside of their own div. So I'm going to say dot and let's just call it actions as a className. I'm gonna put the delete item in here, and then I'm also just going to copy this, because this is gonna be very similar, and this is not going to have a className of delete icon.
This is gonna be the edit icon, and here we are going to call props but instead of handle delete click, we're going to handle the edit click, but we are going to pass in this portfolio item, just like this. Now we'll change the icon we're using later, but for right now let's just see what this gives us and then we can update our styles, as well.
portfolio-sidebar-list.js
<div className="actions"> <a className="edit-icon" onClick={() => props.handleEditClick(portfolioItem)} > <fontAwesomeIcon icon="trash" /> </a> <a className="delete-icon" onClick={() => props.handleDeleteClick(portfolioItem)} >
So, I'm coming here, and you can see we have this little trash icon right next to the big white one. Everything there looks perfectly good.
We'll probably actually be able to reuse this className, so instead of having a edit icon and delete icon, we can just have an action icon and that way we're not duplicating our styles. In fact, let's just change that right now. I'm gonna call that action icon and then we'll just change the name in the style sheet so that both of these can share it.
portfolio-sidebar-list.js
<div className="actions"> <a className="action-icon" onClick={() => props.handleEditClick(portfolioItem)} > <fontAwesomeIcon icon="trash" /> </a> <a className="action-icon" onClick={() => props.handleDeleteClick(portfolioItem)} >
So now let's open up the portfolio-sidebar style sheet, you can see we have this delete icon, let's just call this an action icon.
portfolio-sidebar.scss
.action-icon { cursor: pointer; color: $offwhite; font-size: 1.5em; transition: 0.5s ease-in-out; &:hover { color: $warning; } }
Now if you come back you can see we have both of those icons and now they have the same kind of look and feel.
Now, let's give a little bit of space in between the two of those, and there's a couple of ways that you could do that. We could just add some margin here to left and right, but there's a better way of doing it, and I would be remiss if I showed you a hacky way of doing it. It'd be better to because we already have them wrapped up in a div, I can now put this actions and wrap the action icon inside of it, so let's wrap that up. Now we can use css grid in order to add that margin.
So I can say display grid, grid, template columns. We have two columns, and then we can do some grid gap and for grid gap we can go at, say, 15 pixels, hit save.
portfolio-sidebar.scss
.actions{ display: grid; grid-template-columns: 1fr 1fr; grid-gap: 15px; .action-icon { cursor: pointer; color: $offwhite; font-size: 1.5em; transition: 0.5s ease-in-out; &:hover { color: $warning; } } }
And now if you come back you can see that that is now spaced out properly, and we didn't use any kind of hack like putting margin on the left or right. I don't like using margin if I don't have to when I could use something like grid gap that actually gives us the spacing and it doesn't add spacing in an empty area, if that makes sense.
Now that we have that, let's go and find a good icon. So I'm gonna go to the fontawesome.io site, once again, just like we did with the trash can. There's one called edit, and I use this one quite a bit.
I didn't actually have to look this one up, but I just like to show you my process for that. So here the class name is edit, so if you remember, we have a few steps in order to add an icon. We're first gonna have to open up our app component, and now we're gonna have to bring it in.
Now following the same convention, we're going to have one here that is fa, both in lowercase, and then Edit.
library.add(faTrash, faSignOutAlt, faEdit);
Then from there we're going to have to come down, where else did we add, or was that the only spot? Okay. Oh no, I have to also bring it up in the import. I knew I had two spots to do it. Okay, there we go, so now we have three icons that we're importing that we can use in the application.
app.js
import { faTrash, faSignOutAlt, faEdit } from "@fortawesome/free-solid-svg-icons";
Now if I go to the sidebar here, now instead of trash for the edit, I can just say edit and then passing that as the icon name and props, and we can close this out, and now you can see we have that edit icon, and it has the same type of look and feel that we're wanting.
So lastly, let's just make sure that this is actually working and we're updating state. So we can't see it in the form yet, but if we open up react we will be able to watch how react is performing and we'll be able to see when state gets updated. So let's go and let's grab the portfolio manager component inside of the react div tools, and right here you can see that we have this portfolio to edit, and it's an empty object right now. So that's perfect, that's what we're looking for.
Now if I click on Ministry Safe, or any of these, and click the little edit icon, you can see that now portfolio to edit state has now been replaced with the correct object. I can scale it here so you can see it brought in the name, the position, the thumb image URL, the URL, all of those items, so everything is working perfectly.
We are now populating our state properly, so once someone clicks edit here, then it's going to pass all of that into the edit form so that we have access to it and in the next guide we'll start seeing how we can take that data and we can start populating the form with it.