React for Beginners #11 — Editing and Deleting Items from State

Not the most exciting picture, but I dare you to find better for ‘edit’ and ‘delete’…

This is part 11 of my React Learning series. Using knowledge gleaned from Wes Bos’ React for Beginners.

So far we have our application being able to Create and Read, with a sync to a database and localstorage for relevant parts. Let’s look at Updating and Deleting to get the whole CRUD thing complete.

Coming from a REST API point of view, When we create an Edit form, we have four main steps:

  1. Get the data that currently exists for an item.

React is a similar story, we can use a component, props and state to get up a two way data flow to keep things up to date. The joy of react is doing this ‘live’, seeing those values change the moment the user changes them as opposed to needing a submit action.

Setting up our Edit Component

First of all, lets see about making a component to show the item details we want to edit. Of course, since we are being awesome React devs, we will build a single Edit component inside of our Inventory component and loop through our Groceries object, each time populating the Edit component with existing data for each Grocery.

  1. Make a new class based component called EditGroceryForm

We will flesh it out some more once we have it integrated into our Inventory component.

Adding the State data and Edit Form to our Inventory

There are core things we need in our Inventory component, the state data for our groceries and an edit form for each of them

  1. The parent inventory component currently does not have access to the groceries object in state so we need to pass in the prop: groceries={this.state.groceries}

{Object.keys(this.props.groceries).map( key => <EditGroceryForm grocery={this.props.groceries[key]} key={key}/>)}

Some things to note in the above:

  • We need to need a prop to pass through each grocery.

If all goes to plan, we should have multiple components rendered. However we probably want to show something more helpful than a paragraph tag so lets flesh it out some more…

Setting up the Inputs

So for an edit form to work we do need some inputs. For each grocery we have the following fields:

  • name (input)

If you have already created an add form, it might be useful to copy from there and tweak it.

The really important bits

  • Each of the form elements should have a name property: e.g name='price'

However we will get the following warning at this point: Failed Prop type. You provided a ‘value’ prop to a form field without an onChange handler. Basically will stop us from editting the field as soon as we try to update the field, it will replace it with the entry in State. So we need to change state to change the input which we can do with an onChange event.

The onChange event

First add the event to the form fields: onChange={this.handleChange}

Then we want to make a method that will:

  1. Get the value that was entered (but not displayed)

Lets explain that last line a little:

  • The event.currentTarget.value gives us the value of whatever input triggered the event...

That was a little frightening, but we have one last thing to do, update the state with the updated Object we have just made.

Updating the state

Back in our App component we can make a property for the function that updates the grocery. This requires two arguments:

  1. key - the key for the particular grocery we want to update

This will perform three jobs:

  1. Take a copy of the state: const groceries = [...this.state.groceries]

This is what you should end up with:

Now we have the property, we can pass it to the Inventory using Props: updateGrocery = this.updateGrocery In our Inventory component we again need to pass it into our EditGroceryForm component. However we should now have the updateGrocery method available in our EditGroceryForm component.

However, for the property to work it needs to know the key, the EditGroceryForm component doesn't know what key it is referring to unless we pass that through as a prop. Since we already have a key, lets call it index: index = {key}

So now we have access to it, lets use the method to complete our event:

We now have the input changing state which changes itself based on the user’s input!

Edit — Overview

Using inputs to change values is actually fairly straightforward conceptually:

  1. Set up an input

However, to do it requires a fair amount of props and props flying around so its something that can easily go wrong if you don’t take it step by step.

Appetite for Destruction

So we looked at sorting out an edit form. This means that so far, we have been able to:

  • Create an item

So you can assume the last thing will be…

Delete an Item

This one isn’t too tough as its similar to the process we had before, but even easier. The basic steps are:

  1. Make a method that deletes a certain property from the groceries object.

Our delete method

The delete method is created on our app.js as that is where our state is. It needs to do the following.

  1. Take in a key so we can find the right item to delete.

You might wonder why we dont just delete the item? Well as we are using Firebase, it will have trouble syncing something that doesnt exist so its best to keep the key but with no value.

So to delete a grocery the method should look like this:

We can test it in the console by using $r to select the app component and running: $r.deleteGrocery('grocery1') (assuming 'grocery1' is the key)

Hooking that method to a button

We have the method but we need a way for the user to run it. A button with an event should do the trick!

We can use the edit form before to add a button as follows:

<button onClick={ () => this.props.deleteGrocery(this.props.index)}> Delete </button>

Here we use an inline function to just do it on one line.

Now the last thing to do is pass the deleteGrocery method down to the EditGroceryForm component where the button lives.

I think have talked about props enough but here is the gist of what we want:

  • deleteGrocery={this.deleteGrocery} ... from App JS

If you have your props, button and method correct. It should all work!

Deleting Wrap Up

You should have your deleting sorted. Generally it is easier than editing as you don’t need to worry about swapping it with another value. Just remember to be aware of circumstances where you can actually delete and where its best to leave a ‘null stub’

--

--

All about the things I bumble into as a Web Dev

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store