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
相关产品推荐
相关产品推荐

