如何避免useEffect、useState与useSWR引发的无限循环?
问题分析与解决方案
首先看你贴的代码,有两个明显问题:一是useState初始值设为{},之后执行useStatevar+1会把对象转成NaN,逻辑完全错误;二是你担心的无限循环其实在当前代码里不会发生——因为useSWR的请求key是固定的"demo/data",fetcher也没依赖useStateVar,所以useStateVar更新不会触发useSWR重新请求数据,自然不会反复触发useEffect。不过你的核心需求是用useSWR获取数据、更新状态且不触发循环,下面给你正确的实现方式:
正确实现示例
场景1:基于data更新计数状态
如果只是想在data更新时计数,代码应该这么写:
// 初始值设为数字类型,符合计数需求 const [updateCount, setUpdateCount] = useState(0); const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 }); useEffect(() => { // 先判断data是否存在,避免首次渲染时data为undefined的无效更新 if (data) { // 使用函数式更新,确保拿到最新的状态值 setUpdateCount(prev => prev + 1); } }, [data]); // 仅依赖data,不会引发循环
场景2:从data中提取部分字段更新状态
如果需要从data里提取特定内容更新状态:
const [userProfile, setUserProfile] = useState(null); const { data } = useSWR("demo/data", fetcher, { refreshInterval: 1000 }); useEffect(() => { if (data) { // 只提取需要的字段更新状态,避免冗余 setUserProfile({ nickname: data.nickname, avatar: data.avatarUrl }); } }, [data]);
为什么不会触发无限循环
useSWR的data更新时,会触发依赖data的useEffect执行,更新状态后组件重新渲染;- 但
useSWR的请求key是固定的,fetcher也不依赖我们更新的状态变量,所以状态更新不会触发useSWR重新请求数据,也就不会再次触发useEffect,完全不会形成循环。
另外补充:组件本身会在data更新时自动重新渲染,只要你在组件中使用data或者依赖data的状态变量,就能实现data更新时的重新渲染,不需要额外做触发操作。
内容的提问来源于stack exchange,提问作者forbidden
相关产品推荐
相关产品推荐

