React Native中如何实现仅在函数返回null时自动重新执行该函数?
核心实现思路
- 封装带重试机制的通用请求方法,检测到返回值为null/必填字段缺失时自动重试,同时设置最大重试次数避免无限请求
- 修正原有代码的不规范写法:useState返回值命名颠倒、不要在state中存储JSX元素,改为存储原始数据在渲染层拼接样式与结构
- 两个接口(用户信息、头像)独立配置重试逻辑,互不影响,只有对应接口返回异常时才重试自身
第一步:封装通用重试请求工具
// 通用带重试的请求封装 const fetchWithRetry = async ( fetchFn, validateFn = (res) => !!res, // 默认校验返回值不为null/undefined maxRetries = 3, // 最大重试3次,可根据需求调整 retryDelay = 1000 // 每次重试间隔1秒,可根据需求调整 ) => { let retryCount = 0; while (retryCount < maxRetries) { try { const res = await fetchFn(); // 校验返回值是否符合要求 if (validateFn(res)) { return res; } throw new Error("返回值校验不通过"); } catch (err) { retryCount++; if (retryCount >= maxRetries) { console.error(`重试${maxRetries}次后仍失败:`, err); throw err; } // 等待指定间隔后重试 await new Promise(resolve => setTimeout(resolve, retryDelay)); } } }
第二步:修改组件逻辑
状态声明修正
// 修正useState命名:第一个参数为状态值,第二个为设置函数 const [firstName, setFirstName] = useState('') const [lastName, setLastName] = useState('') const [phone, setPhone] = useState('') const [email, setEmail] = useState('') const [userPhoto, setUserPhoto] = useState(null) // 可选增加加载/错误状态提升用户体验 const [loading, setLoading] = useState(true) const [error, setError] = useState(null)
数据请求逻辑修改
useEffect(() => { const fetchUserData = async () => { setLoading(true); try { // 拉取用户信息,校验必填字段都不为空时才结束请求 const userInfo = await fetchWithRetry( () => server_grab.get_user_info(), (res) => res?.first_name && res?.last_name && res?.phone && res?.email ); setFirstName(userInfo.first_name); setLastName(userInfo.last_name); setPhone(userInfo.phone); setEmail(userInfo.email); // 拉取头像,校验照片数据不为空时才结束请求 const photoInfo = await fetchWithRetry( () => server_grab.download_profile_photo(), (res) => res?.photo_data?.raw_data ); setUserPhoto(photoInfo.photo_data.raw_data); setError(null); } catch (err) { setError("数据加载失败,请稍后重试"); } finally { setLoading(false); } } fetchUserData(); }, [])
渲染逻辑修改
return ( <View> {loading && <Text>加载中...</Text>} {error && <Text style={{color: 'red'}}>{error}</Text>} {userPhoto && <Avatar.Image source= {{uri:`data:image/jpg;base64,${userPhoto}`}}/>} <View> <Text style={styles.title}>{firstName} {lastName}</Text> <Text style={styles.box_text}>{email}</Text> <Text style={styles.box_text}>{phone}</Text> </View> </View> )
方案说明
- 两个接口的校验逻辑独立,仅对应接口返回字段为空时会触发该接口的重试,不会影响另一个接口的正常返回
- 去掉了state中存储JSX的写法,后续修改样式不需要更新状态,直接改渲染层代码即可,性能和可维护性更好
- 增加了加载和错误状态,避免页面空内容用户无法感知加载状态,重试全部失败后也可引导用户手动刷新
内容的提问来源于stack exchange,提问作者MK_Pierce
相关产品推荐
相关产品推荐

