Thinkster
React
CRUD Examples with React & Redux

Example 1: Adding in Delete Functionality for Articles

That's the basics of displaying the article view. Now let's write the ArticleMeta component. This component will display information about the author and edit and delete buttons.

Create src/Article/ArticleMeta.js
import ArticleActions from './ArticleActions';
import { Link } from 'react-router';
import React from 'react';

const ArticleMeta = props => {
  const article = props.article;
  return (
    <div className="article-meta">
      <Link to={`@${article.author.username}`}>
        <img src={article.author.image} />
      </Link>

      <div className="info">
        <Link to={`@${article.author.username}`} className="author">
          {article.author.username}
        </Link>
        <span className="date">
          {new Date(article.createdAt).toDateString()}
        </span>
      </div>

      <ArticleActions canModify={props.canModify} article={article} />
    </div>
  );
};

export default ArticleMeta;

These links are to the profile view, which you'll implement later. This component also will use the 'ArticleActions' component, which is where the edit and delete buttons will live. To enable the delete button, we'll need to add an HTTP call to agent.js for deleting articles.

Update src/agent.js
// ...

const requests = {
  del: url =>
    superagent.del(`${API_ROOT}${url}`).use(tokenPlugin).then(responseBody),
  get: url =>
    superagent.get(`${API_ROOT}${url}`).use(tokenPlugin).then(responseBody),
  post: (url, body) =>
    superagent.post(`${API_ROOT}${url}`, body).use(tokenPlugin).then(responseBody),
  put: (url, body) =>
    superagent.put(`${API_ROOT}${url}`, body).use(tokenPlugin).then(responseBody)
};

const Articles = {
  all: page =>
    requests.get(`/articles?limit=10`),
  del: slug =>
    requests.del(`/articles/${slug}`),
  get: slug =>
    requests.get(`/articles/${slug}`)
};
// ...

Next, let's take a look at the 'ArticleActions' component and implement the delete button.

Create src/Article/ArticleActions.js
import { Link } from 'react-router';
import React from 'react';
import agent from '../../agent';
import { connect } from 'react-redux';

const mapDispatchToProps = dispatch => ({
  onClickDelete: payload =>
    dispatch({ type: 'DELETE_ARTICLE', payload })
});

const ArticleActions = props => {
  const article = props.article;
  const del = () => {
    props.onClickDelete(agent.Articles.del(article.slug))
  };
  if (props.canModify) {
    return (
      <span>

        <Link
          to={`/editor/${article.slug}`}
          className="btn btn-outline-secondary btn-sm">
          <i className="ion-edit"></i> Edit Article
        </Link>

        <button className="btn btn-outline-danger btn-sm" onClick={del}>
          <i className="ion-trash-a"></i> Delete Article
        </button>

      </span>
    );
  }

  return (
    <span>
    </span>
  );
};

export default connect(() => ({}), mapDispatchToProps)(ArticleActions);

mapDispatchToProps() will expose one action, which will be a 'DELETE_ARTICLE' action. It'll use the del function we just added to agent.

If the user can modify this article, we'll display a link to edit the article and a button to delete the article. We'll implement this 'Editor' component later.

Next up, let's handle the 'DELETE_ARTICLE' action in a reducer. The changes will be in the common reducer, since we want to redirect the user to the home view after they delete an article.

Modify the reducer to handle the DELETE_ARTICLE action
// ...

export default (state = defaultState, action) => {
  switch (action.type) {
    // ...
    case 'LOGIN':
    case 'REGISTER':
      return {
        ...state,
        redirectTo: action.error ? null : '/',
        token: action.error ? null : action.payload.user.token,
        currentUser: action.error ? null : action.payload.user
      };
    case 'DELETE_ARTICLE':
      return { ...state, redirectTo: '/' };
  }
  // ...
};

Now, you can find an article on the RealWorld demo, open that article in your local app, and delete it.