无法在 Mern 堆栈应用程序中使用 axios.put 更新 mongodb 对象

Cannot update mogodb object with axios.put in Mern stack app

我需要从我的 mongodb 数据库“评论”集合中更新我的“评论”对象。更具体地说,当我按下“喜欢”按钮时,我想发送一个带有 axios 的放置请求,我可以在其中将 + 1 添加到“评论”对象的“喜欢”。

所有其他操作都正常(获取评论、添加评论等),我唯一遇到困难的是更新评论赞。

如果有人能提供帮助,我将不胜感激。提前致谢!

我在下面添加了我的代码:

//--------CommentComponent.js

import React, { useState, useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { getComments, updateComment } from '../actions/commentActions'

const PostPage = ({ match }) => {
    
const commentz = useSelector(store => store.comment.comments)
const dispatch = useDispatch()

useEffect(() => {
    dispatch(getComments())
}, [dispatch])

const handleLike = e => {
    dispatch(updateComment(e.target.id))
}

return (
    {commentz ? commentz.map(comm => 
        comm.forWich === match.params.id ?
            <div key={comm._id} className={styles.comment}>
                <div>
                    <h2>{comm.name}</h2>
                </div>
                <div>
                     <p>{comm.comment}</p>
                </div>
                     {comm.likes} <button id={comm} onClick={handleLike}>Like</button>
                <div>
            </div>
        : null
    ) : null}
    )
}

export default PostPage

//--------Comment.js

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema
const CommentSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    comment: {
        type: String,
        required: true
    },
    forWich: {
        type: String,
        required: true
    },
    likes: {
        type: Number,
        default: 0
    },
    date: {
        type: Date,
        default: Date.now
    }
});

module.exports = Comment = mongoose.model('comment', CommentSchema);

//--------comments.js

const express = require('express');
const router = express.Router();

// Comments Model
const Comment = require('../../models/Comment');

// @route UPDATE api/comments
// @desc Update comment
// @access Public
router.put('/:id', (req, res, next) => {
    Comment.findbyId(req.params.id)
       .then(comment => comment.update(req.body))
       .catch(next);
})

module.exports = router;

//--------CommentActions.js

import axios from 'axios';
import { 
    GET_COMMENTS,
    ADD_COMMENTS,
    COMMENTS_LOADING,
    GO_COMMENTS,
    UPDATE_COMMENTS
} from './types';



export const updateComment = comment => {
    return function(dispatch) {
        axios
            .put(`/api/comments`, comment)
            .then(res =>
                dispatch({
                    type: UPDATE_COMMENTS,
                    payload: comment
                })
            )
    }
}

//--------CommentReducer.js

import {
    GET_COMMENTS,
    ADD_COMMENTS,
    COMMENTS_LOADING,
    GO_COMMENTS,
    UPDATE_COMMENTS
} from '../actions/types';

const initialState = {
    comments: []
}

export default function(state = initialState, action) {
    switch(action.type) {
        case UPDATE_COMMENTS:
            return {
                ...state,
                comments: state.comments.map(comm => comm._id === action.payload._id ? comm.likes = action.payload + 1 : comm.likes)
    }
}
}

您需要使用:

Comment.findById()

https://mongoosejs.com/docs/api.html#model_Model.findById

您对客户端的放置请求需要类似于:

axios.get(`/api/comments/${comment.id}` comment)

我做了一些改动:

  1. 评论模型“喜欢”变成了一个对象数组,所以我可以存储评论的 ID、喜欢评论的访问者的 ID(将在页面加载时创建,在 localStorage 的帮助下)和单击赞按钮的日期:

models/Comment.js:

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema
const CommentSchema = new Schema({
    likes: [
        {
            commentId: {
                type: String,
                required: true
            },
            userId: {
                type: String,
                required: true
            },
            date: {
                type: Date,
                default: Date.now
            }
        }
    ],
    name: {
        type: String,
        required: true
    },
    email: {
        type: String,
        required: true
    },
    comment: {
        type: String,
        required: true
    },
    forWich: {
        type: String,
        required: true
    },
    date: {
        type: Date,
        default: Date.now
    }
});

module.exports = Comment = mongoose.model('comment', CommentSchema);
  1. 路由已更改,从“put”更改为“post”,因此我添加了整个对象,而不是连接数字:

routes/api/comments:

router.post('/like', (req, res) => {
    const { commentId, userId } = req.body;
    Comment.findById(commentId)
    .then(comment => {
        comment.likes.unshift({ commentId, userId });
        comment.save().then(comment => res.json(comment));

    })
    .catch(err => {
        res.status(404).json({ commentnotfound: "No comment found" })
    });
});
  1. Redux 操作,我将“handleLike”更改为“addLike”

actions/commentActions.js:

export const addLike = ({ commentId, userId }) => {
    return function(dispatch) {
        const config = {
            headers: {
                'Content-Type': 'application/json'
            }
        }
        const body = JSON.stringify({ commentId, userId });

        axios.post(`/api/comments/like`, body, config)
            .then(res => {
                dispatch(getComments())
            }
        )
    }
};

...如您所见,没有任何负载归因于任何类型,因此不再需要使用 UPDATE_COMMENTS,因此也没有减速器。

  1. 最后,前端,在页面加载时,我使用 localStorage 将 Id 分配给新客户端。基于该 Id,我正在创建一个新的 like 对象:

PostPage.js:

useEffect(() => {
    if (!localStorage.getItem(`userId`)) {
        localStorage.setItem(`userId`, uuidv4())
    }
}, [])

const handleLike = e => {
    e.preventDefault()        
    if(localStorage.getItem(`userId`)) {
        const newLike = {
            commentId: e.target.value,
            userId: localStorage.getItem(`userId`)
        }
        dispatch(addLike(newLike))
    }
}