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>
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);
};
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))
};
};
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 }));
};
};
So this is where all the magic happens. Three things are specifically happening:
- We are making a delete request to our back-end
- We are taking the user back to the view of all the stacks
- 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),
};
...
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!
Top comments (0)