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组件单独维护
blogObjectstate,直接用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
相关产品推荐
相关产品推荐

