React+Sinatra后端:点赞/踩按钮代码优化及数据异常修复求助
问题解决方向
一、DRY重构点赞/踩按钮函数
原始两个按钮的函数逻辑高度重复,核心差异仅在于操作的字段(likes/dislikes)和状态更新的目标属性,可以提取通用投票处理函数来复用逻辑:
重构方案示例
// 通用投票处理函数 const handleVote = async (voteType) => { try { // 动态构造请求体,传递对应字段的增量值 const requestBody = { [voteType]: currentCount[voteType] + 1 }; const response = await fetch(`/api/posts/${postId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify(requestBody) }); if (!response.ok) throw new Error('投票请求失败'); const updatedPost = await response.json(); // 根据投票类型更新对应状态 setCurrentCount(prevState => ({ ...prevState, [voteType]: updatedPost[voteType] })); } catch (err) { console.error(err); } }; // 按钮调用方式 <button onClick={() => handleVote('likes')}>点赞 ({currentCount.likes})</button> <button onClick={() => handleVote('dislikes')}>踩 ({currentCount.dislikes})</button>
关键细节说明
- 用计算属性名(
[voteType])动态生成请求体字段和状态更新目标,避免重复编写相似逻辑 - 统一处理异步请求的错误捕获,无需在两个函数中分别编写try/catch
- 若你的状态是分散的(比如单独维护
likes和dislikes状态),可调整状态更新逻辑为:voteType === 'likes' ? setLikes(updatedPost.likes) : setDislikes(updatedPost.dislikes);
二、页面刷新后计数异常的问题
这个问题核心原因是后端PATCH接口未正确累加计数,而是直接覆盖数据库中的值。
后端代码检查与修复
假设你的Sinatra后端原本是错误写法:
patch '/api/posts/:id' do post = Post.find(params[:id]) # 直接用前端传递的值覆盖数据库字段,未做累加 post.update(params[:post]) json post end
正确写法应该基于数据库现有值做增量更新,而非直接赋值:
patch '/api/posts/:id' do post = Post.find(params[:id]) # 判断前端传递的投票类型,对对应字段做+1操作 if params[:likes] post.increment!(:likes) elsif params[:dislikes] post.increment!(:dislikes) end json post end
或者更严谨的方式,直接从数据库获取当前值累加,避免前端传递数值不准确:
patch '/api/posts/:id' do post = Post.find(params[:id]) vote_type = params.keys.find { |k| %w[likes dislikes].include?(k) } if vote_type post.update(vote_type => post[vote_type] + 1) end json post end
问题根源解释
前端每次点击仅传递当前操作的字段(比如点点赞时只传likes: 6),若后端直接用update(params)覆盖,当页面刷新后本地状态重置,后续请求可能传递错误的初始值;而基于数据库现有值累加的方式,能保证计数不受前端状态影响,刷新后数据依然准确。
内容的提问来源于stack exchange,提问作者Maj Aliju
相关产品推荐
相关产品推荐

