如何让useEffect仅在点赞按钮点击时触发,避免初始化自动执行
实现方案
方案1:保留useEffect,新增首次渲染标记
通过useRef存储首次渲染标记,跳过useEffect初始化阶段的执行:
import { useState, useEffect, useRef } from 'react'; const blog = { likeStatus: false } const [liked, setLiked] = useState(blog.likeStatus); // 新增首次渲染标记 const isFirstRender = useRef(true); const likeAPI = (status) => { console.log(status); } useEffect(() => { // 首次渲染直接跳过接口调用,仅修改标记 if (isFirstRender.current) { isFirstRender.current = false; return; } let status = liked ? 'LIKE' : 'DISLIKE'; likeAPI(status); }, [liked]) return ( <div className="App"> <button style={{backgroundColor: liked ? 'green' : 'white'}} onClick={() => setLiked(!liked)} > 点赞 </button> </div> );
方案2(更推荐):移除useEffect,点击时直接触发接口逻辑
原本的点赞操作就是用户主动触发的行为,完全不需要依赖useEffect监听状态变化,直接在点击事件中处理状态更新和接口调用即可,逻辑更简洁也不会产生初始化误调用的问题:
import { useState } from 'react'; const blog = { likeStatus: false } const [liked, setLiked] = useState(blog.likeStatus); const likeAPI = async (status) => { console.log(status); // 实际场景这里是后端请求 } const handleLikeClick = async () => { const newLiked = !liked; // 先更新前端UI(乐观更新) setLiked(newLiked); try { const status = newLiked ? 'LIKE' : 'DISLIKE'; await likeAPI(status); } catch (err) { // 接口请求失败时回滚状态,保证前后端数据一致 setLiked(liked); console.error('操作失败,请重试', err); } } return ( <div className="App"> <button style={{backgroundColor: liked ? 'green' : 'white'}} onClick={handleLikeClick} > 点赞 </button> </div> );
额外优化建议
如果后续需要新增点踩功能,建议将状态从布尔值修改为枚举类型,比如'NONE' | 'LIKE' | 'DISLIKE',可以更清晰的区分未操作、点赞、点踩三种状态,避免逻辑混乱。
内容的提问来源于stack exchange,提问作者shubham karande
相关产品推荐
相关产品推荐

