You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React+Rails购物车项目CRUD操作中Update功能失效求助

React + Rails 评论更新功能故障排查

我是编程新手,正在开发基于React和Rails的购物车项目,评论的CRUD操作里只有Update方法不正常,其他都没问题,麻烦帮忙看看哪里错了?以下是我的代码:

React 组件代码

function Renderreview() {
    const [renderReview, setRenderReview] = useState([])
    const [data, setData] = useState({
      review: "" 
    }) 

    useEffect(() => {
        axios.get('/reviews')
            .then(res => {
                console.log(res)
                setRenderReview(res.data)
            })
            .catch(err => {
                console.log(err)
            })
    }, [])

    function submit(e){
        e.preventDefault();
        axios.post("/reviews",{
            review: data.review,
        })
        .then(res =>{
            console.log(res.data)
        })
    }

    function editReview(id){
       
        axios.put(`/reviews/${id}`,)
        .then(console.log(id))
    }

    function handleDelete(id) {
        axios.delete(`/reviews/${id}`,)
    }
      
      function handle(id){
        const newdata={...data}
        newdata[id.target.id] = id.target.value
        setData(newdata)
        console.log(data)
      }

      function handle2(e){
        const newdata={...renderReview}
        newdata[e.target.id] = e.target.value
        setData(newdata)
        console.log(data)
      }

    return (
        <div className='card1'>

        <div>
            <form className='reviews' onSubmit={(e) => submit(e)}>
                <input onChange={(e)=>handle(e)} id="review" defaultvalue={data.review} placeholder="review" type="text"></input>
                <button>submit review</button>
            </form>
        </div>


            <h2>reviews</h2>
            {renderReview.map((renderReview) => {
                return (
                    <div className='renderedreviews'>{renderReview.review}
                        <button
                            onClick={() => {
                                handleDelete(renderReview.id);
                            }}
                            key={renderReview.review}>
                            Delete
                        </button>

                        <form className='reviews' onSubmit={(id) => editReview(id)}>
                            <input onChange={(id)=>handle2(id)} id="review" defaultvalue={renderReview.review} placeholder="edit" type="text"></input>
                            
                            <button
                            onClick={() => {
                                editReview(renderReview.id);
                            }}
                            key={renderReview.review}>
                            edit
                        </button>
                        </form>
                    </div>
                )
            })}
        </div>
    )
}

Rails 控制器代码

class ReviewsController < ApplicationController 
 
def index
  reviews = Review.all
  render json: reviews
end
 
 
 def update
     review = find_review
       if review
         review.update(review_params)
         render json: review
       else
         render json: {error: "Review not found"}, status: :not_found
     end
 end

def destroy
  review =find_review
  if review.destroy
    head :no_content
  else
    render json: {error: review.errors.messages}, status: 422
  end
end

def create
    review = Review.create(review_params)
    render json: review
  end
 
   private
 
def find_review
  Review.find_by(id: params[:id])
end
 
def review_params
  params.permit(:review)
end
end

问题分析及修复方案

核心错误点

  • 更新请求未携带数据:editReview里的axios.put只传了URL,没把修改后的评论内容发去后端,Rails拿不到更新值自然不会改。
  • 编辑状态管理混乱:handle2函数错误地把评论列表数组renderReview解构后赋值给newdata,再更新到data状态,逻辑完全错误——应该给每个要编辑的评论单独维护输入状态,不能复用全局的data或者直接操作列表数组。
  • 表单逻辑冲突:编辑按钮既绑了onClick又放在form里,form的onSubmit还传错参数,会导致重复触发或者参数混乱。
  • 页面未自动刷新:增删改后都没重新拉取评论列表,页面显示的还是旧数据。

修改后的React组件代码

function Renderreview() {
    const [reviews, setReviews] = useState([]);
    // 用对象存每个评论的编辑内容,key是评论id,value是输入的文本
    const [editInputs, setEditInputs] = useState({});

    // 拉取评论列表的单独函数,方便复用
    const fetchReviews = () => {
        axios.get('/reviews')
            .then(res => setReviews(res.data))
            .catch(err => console.log(err));
    };

    // 组件挂载时拉取评论
    useEffect(() => {
        fetchReviews();
    }, []);

    // 提交新评论
    const handleSubmit = (e) => {
        e.preventDefault();
        const newReviewText = e.target.review.value;
        if (!newReviewText.trim()) return;
        
        axios.post("/reviews", { review: newReviewText })
            .then(() => {
                fetchReviews(); // 提交后刷新列表
                e.target.reset(); // 清空输入框
            })
            .catch(err => console.log(err));
    };

    // 更新评论
    const handleUpdate = (reviewId) => {
        const updatedText = editInputs[reviewId];
        if (!updatedText.trim()) return;
        
        axios.put(`/reviews/${reviewId}`, { review: updatedText })
            .then(() => {
                fetchReviews(); // 更新后刷新列表
                // 清空该评论的编辑输入状态
                setEditInputs(prev => ({ ...prev, [reviewId]: "" }));
            })
            .catch(err => console.log(err));
    };

    // 删除评论
    const handleDelete = (reviewId) => {
        axios.delete(`/reviews/${reviewId}`)
            .then(() => fetchReviews()) // 删除后刷新列表
            .catch(err => console.log(err));
    };

    // 处理编辑输入框的内容变化
    const handleEditInputChange = (reviewId, value) => {
        setEditInputs(prev => ({ ...prev, [reviewId]: value }));
    };

    return (
        <div className='card1'>
            <div>
                <form className='reviews' onSubmit={handleSubmit}>
                    <input 
                        name="review" 
                        placeholder="写点评论..." 
                        type="text"
                    />
                    <button type="submit">提交评论</button>
                </form>
            </div>

            <h2>用户评论</h2>
            {reviews.map((review) => (
                <div className='renderedreviews' key={review.id}>
                    <span>{review.review}</span>
                    <button onClick={() => handleDelete(review.id)}>删除</button>

                    <div className='edit-review'>
                        <input 
                            value={editInputs[review.id] || review.review}
                            onChange={(e) => handleEditInputChange(review.id, e.target.value)}
                            placeholder="编辑评论..." 
                            type="text"
                        />
                        <button onClick={() => handleUpdate(review.id)}>保存修改</button>
                    </div>
                </div>
            ))}
        </div>
    );
}

优化后的Rails控制器代码

class ReviewsController < ApplicationController 
  def index
    reviews = Review.all
    render json: reviews
  end
 
  def update
    review = find_review
    if review
      # 增加更新失败的错误反馈
      if review.update(review_params)
        render json: review
      else
        render json: { error: review.errors.full_messages }, status: :unprocessable_entity
      end
    else
      render json: { error: "评论不存在" }, status: :not_found
    end
  end

  def destroy
    review = find_review
    if review&.destroy
      head :no_content
    else
      render json: { error: "评论不存在" }, status: :not_found
    end
  end

  def create
    review = Review.create(review_params)
    # 增加创建失败的错误反馈
    if review.valid?
      render json: review, status: :created
    else
      render json: { error: review.errors.full_messages }, status: :unprocessable_entity
    end
  end
 
  private
 
  def find_review
    Review.find_by(id: params[:id])
  end
 
  def review_params
    params.permit(:review)
  end
end

内容的提问来源于stack exchange,提问作者Kelvin Matheka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 13:50:24