React中使用useEffect监听Context的写法是否正确?
关于你监听Context的写法分析
整体思路是可行的,但存在几个潜在问题需要修正:
可行的部分
通过useEffect监听data.userData,在它不为空时调用getProfile的逻辑是合理的——Context状态更新会触发组件重渲染,useEffect的依赖数组指定data.userData,能确保该值从空变为有效值时执行异步请求。
潜在问题及修正方案
闭包陷阱导致的旧值引用
getProfile函数内部引用了data.token,但你既没有用useCallback包裹它,也没把它加入useEffect的依赖数组。当data.token更新时,getProfile会一直引用组件上一次渲染时的旧token,导致请求用错凭证。重复请求风险
如果data.userData发生多次变化(比如从某值更新为另一个值),每次都会触发getProfile。如果你的业务只需要在data.userData首次变为非空时请求一次,需要额外判断,或者确保data.userData只在初始化时赋值。错误处理不足
当前catch块仅打印日志,没有给用户反馈错误信息,比如弹窗提示请求失败,用户体验较差。
修正后的代码示例
const { data } = useContext(AuthContext); // 用useCallback包裹,固定函数引用,同时声明依赖 const getProfile = useCallback(async () => { // 先判断token是否存在,避免无意义请求 if (!data.token) return; try { setLoading(true); console.info('getProfile called', data.token); const response = await getByToken(data.token); if (response && response.ok) { setFirstName(response.userData.firstName); setLastName(response.userData.lastName); setEmail(response.userData.email); } } catch (e) { console.info('Error', e); // 新增用户可见的错误提示 alert('获取用户信息失败,请稍后重试'); } finally { setLoading(false); } }, [data.token, setFirstName, setLastName, setEmail]); // 加入所有外部依赖 useEffect(() => { // 同时判断userData和token,确保请求条件更严谨 if (data.userData && data.token) { getProfile(); } }, [data.userData, data.token, getProfile]); // 加入getProfile到依赖
内容的提问来源于stack exchange,提问作者vazquezdev
相关产品推荐
相关产品推荐

