React Native异步无状态组件触发Too many re-renders重渲染报错求助
报错根因
- 组件渲染周期内直接在顶层执行
handleValidUser(),该方法内部调用的setExpanded(true)会触发组件重渲染,重渲染后又会再次执行顶层的handleValidUser(),形成无限循环,直接触发你遇到的Too many re-renders. React limits the number of renders to prevent an infinite loop报错。 - 你的业务逻辑还存在多处隐含错误,即使解决了无限渲染问题也无法正常拿到数据:
- AsyncStorage返回的存储值本身是JSON字符串,需要用
JSON.parse解析,你误用了JSON.stringify,无法正确获取到邮箱字段 - React的state更新是异步操作,调用
setText后立刻读取text拿到的还是更新前的旧值,会导致请求参数错误 - 请求body里引用的
text.toShowLoginEmail字段不存在,你定义的state里只有email字段 getData方法开头判断if (!expanded),但你调用该方法前先把expanded设为了true,逻辑分支永远不会执行,请求根本发不出去
- AsyncStorage返回的存储值本身是JSON字符串,需要用
修复代码
import { BottomNavigation, Text } from 'react-native-paper'; import HomeScreen from './Home'; import PatientScreen from './Patient'; import OtpScreen from './Otp'; import Settings from './settings'; import SearchDoctor from './SearchDoctor'; import AsyncStorage from '@react-native-async-storage/async-storage'; // 注意补全AsyncStorage的导入,原代码漏了 import React, { useEffect } from 'react'; const PatientPage = ({ navigation }) => { const [expanded, setExpanded] = React.useState(true); const [index, setIndex] = React.useState(0); const [text, setText] = React.useState({ email: '' }); const [routes] = React.useState([ { key: 'music', title: 'Music', icon: 'queue-music' }, { key: 'search', title: 'Search', icon: 'magnify' }, { key: 'settings', title: 'Settings', icon: 'cog-outline' }, ]); const getData = async () => { try { const data = await AsyncStorage.getItem('@storage_Key'); const value = JSON.parse(data); // 改用parse解析JSON字符串 const userEmail = value.email; // 更新state setText(prev => ({ ...prev, email: userEmail })); // 直接用解析出来的邮箱发请求,避免state异步问题 const response = await fetch("http://localhost:8090/patient/fetchData", { method: "POST", headers: { "Content-type": "application/json; charset=utf-8", }, body: JSON.stringify({ email: userEmail // 用实际取到的邮箱值 }) }); const resData = await response.json(); console.log(resData); setExpanded(true); // 拿到数据后再设置expanded状态 } catch (e) { console.error('读取存储或请求失败:', e); } } // 只在组件挂载时执行一次请求逻辑,避免循环渲染 useEffect(() => { getData(); }, []); const renderScene = BottomNavigation.SceneMap({ music: HomeScreen, search: SearchDoctor, settings: Settings, }); return ( <BottomNavigation navigationState={{ index, routes }} onIndexChange={setIndex} renderScene={renderScene} /> ); } export default PatientPage;
内容的提问来源于stack exchange,提问作者Ankit Vashishta
相关产品推荐
相关产品推荐

