We have one CRUD method working and a few buttons that throw errors when you try clicking them, so let’s go ahead and take care of that. The delete method that we’re passing to our cat component is simple enough.

deleteCat = (cat) => {

api.deleteCat(cat.id)

.then(res => {

const cats = this.state.cats.filter(c => c.id != cat.id)

this.setState({ cats: cats })

})

}

Now, clicking the delete button in the Cat component calls the function passed into it as delete , which we can see in our renderCats() method is our App component’s deleteCat() . This calls our API’s method of the same name, and then instead of doing anything with the response, we’re being lazy and just filtering out our deleted cat from state.

The edit method is going to be a little more complicated out of DRY laziness. I want to edit cats in a modal, but I also want to use a modal to create new cats, so let’s take a detour and return to it at the end. First, let’s style up a modal in App.scss .

.container {

display: flex; .add {

margin-right: 20px;

padding: 0 20px;

height: 30px;

border-width: 0;

outline: none;

border-radius: 2px;

box-shadow: 0 1px 4px rgba(0, 0, 0, .6);

background-color: #2ecc71;

color: #ecf0f1;

transition: background-color .3s; &:hover, &:focus {

background-color: #27ae60;

}

}

} .modal {

display: none;

position: fixed;

z-index: 1;

left: 0;

top: 0;

width: 100%;

height: 100%;

overflow: auto;

background-color: rgba(0, 0, 0, 0.4); .modal-content {

background-color: #fff;

margin: 15% auto;

padding: 20px;

width: 40%;

border-radius: 10px;

}

} .show {

display: block;

}

Notice that show class on the bottom? That’s for our modal. We’re going to also going to sidestep React for the functionality just a little by adding

window.onclick = event => {

if (event.target === modal) {

modal.classList.toggle('show')

}

}

in our App.js but outside of the component itself. Popups are awful and it’s much easier to just click outside of them to make them go away rather than find the x button or whatever.

Next, we’ll set up our EditCat.js component, which we’ll use both for editing existing cats and creating new ones.

import React from 'react'

import './EditCat.scss' const EditCat = props =>

<div className="edit-cat">

<div>

<input

className="input"

type="text"

defaultValue={ props.name }

onChange={ props.updateName } />

<label className="label">Name: </label>

</div>

<div>

<input

className="input"

type="text"

defaultValue={ props.image_url }

onChange={ props.updateImage } />

<label className="label">Image Url: </label>

</div>

<div>

<textarea

rows="2"

className="textarea"

defaultValue={ props.bio }

onChange={ props.updateBio } />

<label className="label">Bio: </label>

</div>

<div>

<input

className="input"

type="text"

defaultValue={ props.kills }

onChange={ props.updateKills } />

<label className="label">Kill Count: </label>

</div>

<div className="buttons">

<button className="edit"

onClick={ props.saveEdits }>Save Edits</button>

</div>

</div> export default EditCat

Again, we’re using a stateless functional component. Here, each input is pre-populated with the value passed down to it, which will be the current cat’s stats, or empty if we’re making a new cat. Each input is also echoing up its current value with the updateWhatever() function that’s being passed down to it.

Seeing how we render EditCat.js inside App.js makes this clearer. (Don’t forget to import it import EditCat from './components/EditCat' )

renderEditModal = () =>

<EditCat

name={this.state.editingCat.name}

image_url={this.state.editingCat.image_url}

bio={this.state.editingCat.bio}

kills={this.state.editingCat.kills}

updateName={this.updateName}

updateImage={this.updateImage}

updateBio={this.updateBio}

updateKills={this.updateKills}

saveEdits={

this.state.isNew ? this.saveNewCat : this.saveEdits

} />

The cat stats are being passed down from something in our state called editingCat that we haven’t created yet but will shortly. There are also a bunch of edit methods we’ve yet to write. Finally, there’s a ternary expression that checks the state to see whether the EditCat in the modal is new or old. If it’s new, we’re calling a saveNewCat() method; if not, we call saveEdits() .

Let’s first update our render method:

render = () =>

<div className="page">

<h1>PrrrStack Cat Demo</h1>

<div className="container">

<button className="add"

onClick={this.addNewCat}>Add another cat</button>

</div>

<div className="container">

{ this.renderCats() }

<div id="modal" className="modal">

<div className="modal-content">

{ this.state.editingCat ? this.renderEditModal() : '' }

</div>

</div>

</div>

</div>

So if our state says we’re editing a cat, call the renderEditModal() function. Otherwise, display nothing. We also have a new button for adding a new cat. Finally, let’s update our state to include everything we’ll need:

this.state = {

cats: [],

editingCat: null,

isNew: false,

}

That should guarantee that our app doesn’t break when it renders, but we still have to set up the methods before it’s working.