开发者问题收集

Mern,删除评论问题

2020-01-21
384

我无法删除单个帖子内的评论。我不知道是什么原因造成的,但显然我遇到了 404 错误,说实话,我不知道为什么找不到帖子。我很想得到帮助,看看是什么原因造成的,为什么我会收到这个错误,以及为什么我无法从帖子中删除评论。下面我将发布一些我的后端以及前端代码,但我也会确保在下面链接到我的 Github。我已经为此挣扎了将近 3 天,我不知道到底是什么导致了错误,我需要一些帮助。 另外要说的是,我对 MERN 还很陌生,所以也请看看我的 Github 代码,并提出修改或我可以做得更好的建议,说实话,这对我来说意义重大。 下面是一些代码以及我针对此特定项目的 Github Repo 链接

https://github.com/tigerabrodi/ELance

从中删除评论的路线发布

// @route    DELETE api/posts/comment/:commentId 
// @desc     Delete comment
// @access   Private
router.delete("/comment/:commentId", auth, async (req, res) => {
  try {
    const comment = await Comment.findById(req.params.commentId);

    if (!comment) {
      return res.status(404).json({ msg: "Comment do not exist" });
    }

    if (comment.user.toString() !== req.user.id) {
      return res.status(401).json({ msg: "User not authorized" });
    }

    await comment.remove();

    res.json({msg: "Comment Removed"})
  } catch (err) {
    console.error(err.message);
    res.status(500).send("Server Error");
  }
});

module.exports = router;

Post.js

import React, { Fragment, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import Spinner from '../layout/Spinner';
import PostItem from '../posts/PostItem';
import CommentForm from '../post/CommentForm';
import CommentItem from '../post/CommentItem';
import { getPost } from '../../redux/post/post.actions';
import {getSinglePostComments} from "../../redux/comment/comment.actions"

const Post = ({ getPost, getSinglePostComments, post: { post, loading }, comment, match }) => {
  useEffect(() => {
    getPost(match.params.id);
    getSinglePostComments(match.params.id)
  }, [comment.comments]);

  return loading || comment.loading || post === null ? (
    <Spinner />
  ) : (
    <Fragment>
      <Link to='/posts' className='btn btn-info m-3'>
        Back To Posts
      </Link>
      <PostItem post={post} showActions={false} />
      <CommentForm postId={post._id} />
      <div className='comments'>
        {comment.comments.map(comment => (
          <CommentItem key={comment._id} comment={comment} />
        ))}
      </div>
    </Fragment>
  );
};

const mapStateToProps = state => ({
  post: state.post,
  comment: state.comment
});

export default connect(
  mapStateToProps,
  { getPost, getSinglePostComments }
)(Post);

CommentItem.js

import React from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import Moment from 'react-moment';
import {deleteComment} from '../../redux/comment/comment.actions';
import defaultUserImage from "../../assets/default-user-icon.jpg"

const CommentItem = ({
  comment: { _id, text, user, date },
  auth,
  deleteComment
}) => (

    <div class="card m-5 bg-warning">
  <div class="row no-gutters align-items-center">
    <div class="col-md-2">
    <Link to={`/profile/${user._id}`}>
            <img className='card-img rounded-circle pl-2' src={user.avatar ? user.avatar : defaultUserImage} alt='' />
            </Link>
    </div>
    <div class="col-md-10">
      <div class="card-body">
        <h5 class="card-title text-center">{user.name}</h5>
        <p class="card-text">{text}</p>
        <p class="card-text"><small class="text-muted">Posted on <Moment format='YYYY/MM/DD'>{date}</Moment>
</small></p>
      {!auth.loading && user._id === auth.user._id && (
        <button
          onClick={() => deleteComment(_id)}
          type='button'
          className='btn btn-danger float-right mb-4'
        >
          <i className='fas fa-times' />
        </button>
      )}
      </div>
    </div>
  </div>
</div>
);

const mapStateToProps = state => ({
  auth: state.auth
});

export default connect(
  mapStateToProps,
  { deleteComment }
)(CommentItem);

CommentForm.js

import React, { useState } from 'react';
import { connect } from 'react-redux';
import { addComment } from '../../redux/comment/comment.actions';

const CommentForm = ({ postId, addComment }) => {
  const [text, setText] = useState('');

  return (
    <div className='container'>
        <div className="row">
        <div className="col text-center">
         <div>
        <h4>Leave a Comment</h4>
      </div>
      <form
        className='form my-1 d-flex flex-row align-items-center justify-content-center'
        onSubmit={e => {
          e.preventDefault();
          addComment(postId, { text });
          setText('');
        }}
      >
        <textarea
          name='text'
          className="form-control bg-info text-light"
          placeholder='Comment the post'
          value={text}
          onChange={e => setText(e.target.value)}
          required
        />
        <input type='submit' className='btn btn-outline-info ml-3' value='Submit' />
      </form>
    </div>
        </div>
        </div>

  );
};

export default connect(
  null,
  { addComment }
)(CommentForm);

comment.actions.js

import axios from "axios";
import {setAlert} from "../alert/alert.actions"
import {CommentActionTypes} from "./comment.types"


// Get Comments For a Single Post
export const getSinglePostComments = id => async dispatch => {
  try {
    const res = await axios.get(`/api/posts/comments/${id}`);

    dispatch({
      type: CommentActionTypes.GET_SINGLE_POST_COMMENTS,
      payload: res.data
    });
  } catch (err) {
    dispatch({
      type: CommentActionTypes.COMMENT_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};



  // Add Comment
  export const addComment = (postId, formData) => async dispatch => {
    const config = {
      headers: {
        'Content-Type': 'application/json'
      }
    };

    try {
        const res = await axios.post(`/api/posts/comment/${postId}`, formData, config);

        dispatch({
          type: CommentActionTypes.ADD_COMMENT,
          payload: res.data
        });
      } catch (err) {
        dispatch({
          type: CommentActionTypes.COMMENT_ERROR,
          payload: { msg: err.response.statusText, status: err.response.status }
        });
      }
  }

 // Delete comment
export const deleteComment = (commentId) => async dispatch => {
  try {
    await axios.delete(`api/posts/comment/${commentId}`);

    dispatch({
      type: CommentActionTypes.DELETE_COMMENT,
      payload: commentId
    });

    dispatch(setAlert('Comment Removed', 'success'));
  } catch (err) {
    dispatch({
      type: CommentActionTypes.COMMENT_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};  

comment.reducer.js

import {CommentActionTypes} from "./comment.types";



const initialState = {
    comments: [],
    loading: true,
    error: {}
}

const commentReducer = (state = initialState, action) => {
    const {payload, type} = action;
    switch (type) {
            case CommentActionTypes.GET_SINGLE_POST_COMMENTS:
                return {
                    ...state,
                    comments: payload,
                    loading: false
                }
            case CommentActionTypes.ADD_COMMENT:
                return {
                    ...state,
                    comments: [payload, ...state.comments],
                    loading: false
                }
            case CommentActionTypes.DELETE_COMMENT:
                return {
                    ...state,
                    comments: state.comments.filter(comment => comment._id !== payload),
                    loading: false
                }
            case CommentActionTypes.COMMENT_ERROR:
                return {
                    ...state,
                    error: payload,
                    loading: false
                }
        default:
            return state;
    }
}

export default commentReducer

comment.types.js

export const CommentActionTypes = {
    DELETE_COMMENT: "DELETE_COMMENT",
    ADD_COMMENT: "ADD_COMMENT",
    COMMENT_ERROR: "COMMENT_ERROR",
    GET_SINGLE_POST_COMMENTS: "GET_SINGLE_POST_COMMENTS"
}
1个回答

在 comment.actions.js deleteComment 方法中,需要在删除 url 开头添加斜线:

await axios.delete(`/api/posts/comment/${commentId}`);
SuleymanSah
2020-01-22