为何使用axios GET请求搭配React Redux时会出现无限循环?
问题根因
你的无限循环本质是useEffect依赖的userId和isAdmin每次都被判定为发生变更,导致反复触发请求、更新Redux状态的流程,核心原因有两个:
- 类型不一致导致的全等比较失败
你初始状态里userId和isAdmin的默认值是空字符串"",但后续更新这两个字段时(比如SET_USER_INFO、SET_USER_IS_ADMIN等action),传入的值大概率是数字类型(比如userId: 123、isAdmin: 1)。React的依赖比较用的是全等===,字符串和数字哪怕字面量相同也会被判定为不同的值,导致useEffect反复触发。 - 无守卫的请求触发逻辑
初始状态下userId和isAdmin是空值,此时就会发起第一次请求,请求返回后如果又调用SET_USER_INFO更新这两个字段,就会触发第二次useEffect执行,如果类型不一致就会进入死循环。
解决方案
1. 统一Redux状态的字段类型
修改reducer的初始值,匹配后续赋值的类型,避免类型混乱导致的比较失败:
const intitialState = { // 其余字段不变 userId: null, // 原空字符串改为null,后续统一存字符串/数字类型的userId isAdmin: null, // 原空字符串改为null,后续统一存0/1数字类型的管理员标记 // 其余字段不变 };
同时要保证所有更新userId、isAdmin的action,传入的payload类型和你约定的保持一致,不要一会传数字一会传字符串。
2. 给useEffect增加守卫条件
只有userId和isAdmin都有有效值时才发起请求,避免空值状态下的无效触发:
useEffect(() => { // 空值直接返回,不发起请求 if (!userId || isAdmin === null) return const userInfo = { userId, typeOfId: isAdmin ? "admin_id" : "user_id", }; dispatch(allEntries(userInfo)); }, [userId, isAdmin, dispatch]);
(可选)强制统一取值类型
如果没法保证其他地方更新这两个字段时的类型一致,可以在useSelector取值时直接做类型转换,保证每次拿到的值类型统一:
// 统一转成字符串 const userId = useSelector((state) => String(state.userInfoReducer.userId)); // 统一转成数字 const isAdmin = useSelector((state) => Number(state.userInfoReducer.isAdmin));
内容的提问来源于stack exchange,提问作者Tim Taylor
相关产品推荐
相关产品推荐

