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

React点赞按钮仅首次更新状态 多次触发PUT请求点赞数未增长

问题根因与修复方案

从你给出的请求日志可以看到所有PUT请求携带的likes值都是9,说明问题出在前端生成点赞数的逻辑,同时后端接口也存在响应缺失的问题,具体修复步骤如下:


1. 修复Blog组件点赞取值逻辑

你在likeBlog方法里计算点赞数时,一直用的是组件首次渲染时传入的blog props初始值,没有用到更新后的props或者本地state的最新值,所以每次计算出来的likes都是初始值+1,自然不会递增。

修复代码:

const likeBlog = () => {
  // 从本地维护的blogObject state取最新点赞数,不要用初始props的blog
  let likes = blogObject.likes + 1;
  const editedBlog = { ...blogObject, likes };
  updateBlog(editedBlog);
  setBlogObject(editedBlog);
};

更优方案:无需在Blog组件单独维护blogObject state,直接用App层同步过来的props即可,简化后的代码如下:

const Blog = ({ blog, updateBlog }) => {
  ...
  const likeBlog = () => {
    const editedBlog = { ...blog, likes: blog.likes + 1 };
    updateBlog(editedBlog);
  };

  return (
    ...
    <Button
      variant='success'
      type='submit'
      style={{ marginLeft: '8px' }}
      onClick={likeBlog}
    >
      {/* 直接用props的likes,不用本地state */}
      {blog.likes} likes
    </Button>
    ...
  )
}

2. 修复后端PUT接口无响应问题

你在后端的put路由里,更新完数据之后没有把结果返回给前端,前端的blogService.update拿不到最新的后端数据,会导致App层的updatedBlog异常。

修复代码:

blogsRouter.put('/:id', async (request, response, next) => {
  const body = request.body;

  const blog = {
    author: body.author,
    title: body.title,
    url: body.url,
    likes: body.likes,
  };

  try {
    const editedBlog = await Blog.findByIdAndUpdate(request.params.id, blog, {
      new: true,
    });
    // 新增返回响应的逻辑
    response.json(editedBlog.toJSON());
  } catch (exception) {
    next(exception);
  }
});

3. 优化App层状态更新逻辑(可选,避免并发更新异常)

你在updateBlog里调用setBlogs的时候,直接用了当前作用域的blogs变量,这个变量是闭包捕获的旧值,在并发更新场景下可能会有状态覆盖的问题,推荐改成函数式更新:

const updateBlog = async blogObject => {
  const updatedBlog = await blogService.update(blogObject.id, blogObject);
  // 用函数式更新,取最新的state值
  setBlogs(prevBlogs =>
    prevBlogs.map(blog => (blog.id !== updatedBlog.id ? blog : updatedBlog)),
  );
  // 其余原有逻辑保持不变
  console.log(updatedBlog);
  setMessage(`Liked "${updatedBlog.title}"`);
  setMessageClass('success');
  setTimeout(() => {
    setMessage(null);
    setMessageClass('none');
  }, 3000);
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 17:24:03