疑问:该useEffect是否仅在cachedUsers为空时执行?求优化方案
当前写法的问题(无意义,甚至存在逻辑错误)
- 冗余的
useMemo:cachedUsers只是fsUsers的引用拷贝,没有任何缓存优化价值,反而增加了不必要的计算开销,完全可以直接使用fsUsers。 - 错误的
useEffect依赖:[!cachedUsers.length]会导致请求被触发两次:- 初始时列表为空,
!0为true,执行请求; - 请求成功后列表有数据,
!length变为false,依赖项变化,会再次发起无效请求——这完全违背了“仅在列表为空时执行”的需求。
- 初始时列表为空,
更优实现方案
根据你的实际需求,分两种场景给出最优写法:
场景1:仅在组件首次挂载且列表为空时请求一次(最常用)
去掉冗余代码,在useEffect内部加长度判断,同时用空依赖确保只执行一次:
import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import axios from "axios"; const GetAllUsers = () => { const [fsUsers, setFsUsers] = useState([]); const [notFoundErr, setNotFoundErr] = useState(""); const [loading, toggleLoading] = useState(true); const navigate = useNavigate(); useEffect(() => { // 仅当列表为空时发起请求 if (fsUsers.length !== 0) return; const fetchUsers = async () => { try { toggleLoading(true); const res = await axios({ method: "GET", url: "http://localhost:4000/auth/api/firebase/users", validateStatus: (status) => status === 200 || status === 404, }); if (res.status === 200) { setFsUsers(res.data); setNotFoundErr(""); // 请求成功时清空之前的错误信息 } else if (res.status === 404) { setNotFoundErr("No users found."); } } catch (error) { console.error(error); navigate("/error500"); } finally { toggleLoading(false); } }; fetchUsers(); }, []); // 空依赖确保仅组件挂载时执行一次 return [fsUsers, notFoundErr, loading]; }; export default GetAllUsers;
场景2:需要在列表被清空时自动重新请求(比如有清空操作)
保留对列表长度的依赖,确保每当列表变为空时触发请求:
import { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; import axios from "axios"; const GetAllUsers = () => { const [fsUsers, setFsUsers] = useState([]); const [notFoundErr, setNotFoundErr] = useState(""); const [loading, toggleLoading] = useState(true); const navigate = useNavigate(); useEffect(() => { // 仅当列表为空时发起请求 if (fsUsers.length !== 0) return; const fetchUsers = async () => { try { toggleLoading(true); const res = await axios({ method: "GET", url: "http://localhost:4000/auth/api/firebase/users", validateStatus: (status) => status === 200 || status === 404, }); if (res.status === 200) { setFsUsers(res.data); setNotFoundErr(""); } else if (res.status === 404) { setNotFoundErr("No users found."); } } catch (error) { console.error(error); navigate("/error500"); } finally { toggleLoading(false); } }; fetchUsers(); }, [fsUsers.length]); // 依赖列表长度,长度变为0时触发请求 return [fsUsers, notFoundErr, loading]; }; export default GetAllUsers;
额外优化点
- 请求成功时清空错误信息,避免之前的404提示残留;
- 简化
validateStatus的写法,去掉不必要的冗余判断; - 去掉
res &&判断:axios在validateStatus允许的状态下不会抛出错误,res一定存在。
内容的提问来源于stack exchange,提问作者dBish6
相关产品推荐
相关产品推荐

