#reactjs #react-native
Вопрос:
Столкнулся со слишком большим количеством повторных рендеров. React ограничивает количество отрисовок, чтобы предотвратить бесконечный цикл для собственного кода React в моем коде в асинхронном компоненте без состояния.
Я пытаюсь вызвать асинхронный метод, используя компонент без состояния. Я пытаюсь вызвать API внутри асинхронного хранилища.
Поэтому в основном мне нужно получить электронное письмо от Asyncstorage и передать эту ссылку в API. Я пытаюсь это сделать, но получаю ошибку, сталкиваясь со Слишком большим количеством повторных рендеров. React ограничивает количество рендеров, чтобы предотвратить бесконечный цикл
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';
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 () => {
if (!expanded)
try {
AsyncStorage.getItem('@storage_Key').then((data) => {
let value = JSON.stringify(data);
setText({
...text,
email: value.email
})
fetch("http://localhost:8090/patient/fetchData", {
method: "POST",
headers: {
"Content-type": "application/json; charset=utf-8",
},
"body": JSON.stringify({
email: text.toShowLoginEmail
})
}).then(response => response.json()).then(response => {
console.log(response);
})
})
} catch (e) {
// error reading value
}
}
const handleValidUser = () => {
setExpanded(true);
getData();
}
handleValidUser();
const renderScene = BottomNavigation.SceneMap({
music: HomeScreen,
search: SearchDoctor,
settings: Settings,
});
return (
<BottomNavigation
navigationState={{ index, routes }}
onIndexChange={setIndex}
renderScene={renderScene}
/>
);
}
export default PatientPage;```
Ответ №1:
Проблема в том, что Вы вызываете handleValidUser();
тело компонента, и транс происходит вот так handleValidUser() -> getData() -> setText()
.
Так handleValidUser
вызывается при каждом рендеринге, но сама функция изменяет состояние, что вызывает повторный рендеринг и другой вызов handleValidUser
, создавая таким образом цикл
рассмотрите возможность использования useEffect
для вызова функции только один раз или только при изменении определенных зависимостей
// Don't forget to import { useEffect } from 'react'
useEffect(() => {
handleValidUser();
}, []);
В этом случае массив зависимостей пуст, поэтому функция будет вызвана только один раз, когда компонент монтируется (очень похоже componentDidMount
. Для более сложного использования массива зависимостей см. раздел React useEffect.
По-видимому, существуют некоторые зависимости, поэтому следующее может помочь.
const getData = React.useCallback(async () => {
if (!expanded){
try { ....
}
}, [expanded]); //add expanded as a dependency
const handleValidUser = React.useCallback(() => {
setExpanded(true);
getData();
}, [setExpanded, getData)
Наконец, измените крючок useEffect
useEffect(() => {
handleValidUser()
}, [handleValidUser]);
Таким образом, каждый раз useCallback
, когда изменяется зависимость, функция также изменяется, что приводит к повторному срабатыванию эффекта использования.
Комментарии:
1. Попробовал, эта ошибка исчезла, но API еще не вызывается при загрузке
2. Это потому
if(!expanded)
, что не сработает. Я изменю код, пожалуйста, попробуйте это.3. Да, пожалуйста, внесите изменения и поблагодарите меня. Я совсем новичок в реагировании на родной язык