React使用useState触发axios请求无限死循环该如何修复?
问题修复方案
根本原因
你的useEffect未指定依赖数组,每轮组件渲染完成后都会自动执行。而副作用内部调用setUsers更新users状态会触发组件重渲染,重渲染后又再次执行useEffect、更新状态,形成无限循环。
修复步骤
- 给
useEffect添加空依赖数组[]作为第二个参数,让副作用仅在组件首次挂载时执行一次。同时可以补充请求取消逻辑,避免组件卸载后未完成的请求触发状态更新导致内存泄漏,修改后的代码如下:
const [ users, setUsers ] = useState([]); useEffect(() => { // 声明请求取消标识 const source = axios.CancelToken.source(); const config = { headers: { Authorization: 'Bearer ' + localStorage.getItem('token') }, cancelToken: source.token } axios.get('users', config).then((res) => { if (res.status == 200 && res.data.msg == "success") { setUsers(res.data.users) } else { history.push("/"); } feather.replace() }).catch(err => { // 忽略主动取消的请求报错 if (axios.isCancel(err)) return; console.error('请求失败:', err) }); // 组件卸载时主动取消未完成的请求 return () => source.cancel(); // 空依赖数组,仅组件首次挂载时执行一次 }, []);
- 补充代码规范优化:React中不支持用
class指定DOM类名,你渲染列表的代码里class="delete"需要改为className="delete",修改后代码如下:
function getRows(users) { return users.map(user => { const { u_id, username } = user; return ( <tr key={u_id} id={u_id}> <td>{u_id}</td> <td>{username}</td> <td className="delete"> <a href="javascript:void(0)"><span data-feather="edit"></span></a><a href="javascript:void(0)" onClick={(e) => deleteUser(e, u_id)}><span data-feather="trash"></span></a> </td> </tr> ) }); }
- 如果后续你在删除、编辑用户之后需要刷新列表,可以把请求用户列表的逻辑抽成独立函数,操作成功后手动调用即可,不需要修改
useEffect的依赖配置。
内容的提问来源于stack exchange,提问作者Akhilesh
相关产品推荐
相关产品推荐

