React useEffect添加value依赖触发无限循环,空依赖页面不更新求解
问题根因
你把value加入useEffect依赖数组触发无限循环的原因非常明确:
- useEffect回调执行时会调用
getBCAccount,接口返回后会执行setValue修改value的值 - 依赖数组中的
value发生变化后,会再次触发useEffect回调执行,形成「调用接口→修改value→触发useEffect→再调用接口」的死循环 - 你监听
value变化来拉取新数据的逻辑本身是本末倒置的:value本身就是拉取接口后的结果,用结果触发重新拉取必然会死循环。
解决方案
你完全不需要监听value变化,只需要在新增账户的接口请求成功后,手动触发一次账户列表拉取即可,修改后代码如下:
export default function BC() { const [value, setValue] = useState([]) async function getBCAccount() { const result = await axios.get("http://localhost:3004/accounts") if(result) { setValue(result.data) } } async function createBCAccount() { const result = await axios.post("http://localhost:3004/accounts", { id: 5, name: "mmm" }) // 新增成功后直接调用拉取列表逻辑 if(result) { await getBCAccount() } } // 保留空依赖,只在首次渲染时拉取一次初始列表 useEffect(()=> { getBCAccount() }, []) const handleAddAccount = () => { createBCAccount() } return ( <BcContainer> <button onClick={handleAddAccount}>add</button> {value && value.map((v)=> ( <AccountContainer key={v.id} to={`/bc/${v.id}`}> <p>{v.name}</p> <p>{v.coin} BTC</p> </AccountContainer> ))} </BcContainer> ) }
可选优化方案
如果你有多个场景会触发列表刷新,也可以新增一个独立的刷新触发器状态,避免重复写拉取逻辑:
- 定义
const [refreshFlag, setRefreshFlag] = useState(0) - 任意需要刷新列表的位置执行
setRefreshFlag(prev => prev + 1) - useEffect依赖数组改为
[refreshFlag]即可,同样不会出现无限循环问题。
内容的提问来源于stack exchange,提问作者OSW
相关产品推荐
相关产品推荐

