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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 04:05:28