DEV Community

loading...

Deleting with React & Redux

szam profile image Samuel Grasse-Haroldsen ・3 min read

I recently added delete functionality to to my flashcard/quiz application, Flipr Quiz. This may not sound super exciting to people, but adding this functionality really helped me review so many parts of the front-end: React events, Redux actions and reducers, higher-order functions, and more.

Flipr Quiz

I originally designed my app to be simple, eye-catching, and functional. It is made up of two resources: stacks and cards. Users create a stack with a title and then add cards (front and back) to a certain stack. Today we'll only cover deleting stacks.

The Back-End

This post is about React and Redux so I won't go to into the back-end, but I will say I like to start adding new features on the back-end. This way I know that my back-end isn't the problem while testing on the front-end. Using Ruby on Rails all I need to do is add a destroy method to my stacks controller and make sure I have dependent_destroy listed on the card relationship on my stack model (I want cards to be deleted when a stack is deleted).

React

Now that my back-end is ready to destroy stacks, I like to get something visual on the page. I add a "Delete this stack" button to the stack view page.

<button onClick={this.handleClick}>
  Delete this stack
</button>

Enter fullscreen mode Exit fullscreen mode

I know I don't have a handleClick method in this class, so I write that next. I'll need the stack's id because my back-end needs to know which stack to delete. I'll also need to access the history object to alter our URL. I'm using React Router which gives me access to additional props like parts of the URL ex) params, history. Read more about match and history at reactrouter.com.

handleClick = () => {
  const { history } = this.props;
  this.props.deleteStack(this.props.match.params.id, history);
};
Enter fullscreen mode Exit fullscreen mode

I don't have a deleteStack action yet, but I'll go ahead a map it to props before I forget.

const mapDispatchToProps = (dispatch) => {
  return {
    deleteStack: (id, history) => dispatch(deleteStack(id, history))
  };
};
Enter fullscreen mode Exit fullscreen mode

Redux

Now I'll go ahead and finally add the deleteStack action to my stacksActions.js. (btw I'm using redux-thunk to do async things)

export const deleteStack = (id, history) => {
  return (dispatch) => {
    fetch(`http://localhost:3000/stacks/${id}`, {
      method: "DELETE",
      headers: { "Content-Type": "application/json" },
    })
      .then(() => history.push("/stacks"))
      .then(() => dispatch({ type: "DELETE_STACK", payload: id }));
  };
};
Enter fullscreen mode Exit fullscreen mode

So this is where all the magic happens. Three things are specifically happening:

  1. We are making a delete request to our back-end
  2. We are taking the user back to the view of all the stacks
  3. We are dispatching our DELETE_STACK action with the id of our stack as the payload

Stack Reducer

Now that we have our action we need to add how our state should change based on this action in our reducer!

switch (action.type) {
...
  case "DELETE_STACK":
    return {
      data: state.data.filter((stack) => stack.id !== action.payload),
    };
...
Enter fullscreen mode Exit fullscreen mode

Here we are filtering out the specific stack that we just deleted using our payload (the stack's id). Now our stack has been deleted on the back and front end!

Discussion (0)

pic
Editor guide