skip to Main Content

I’m having an infinite loop due to the change of state on react native, the problem is that I tried to fix it with Use Effect Hook and was impossible.

That is my code

import React from 'react';
import { Alert } from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage'
import Constants from 'expo-constants';
import Leaderboard from 'react-native-leaderboard';
import { useEffect } from 'react/cjs/react.production.min';

const LeaderBoardScreen = ({ navigation }) => {
    const baseUrl = Constants.manifest.extra.backend_url;
    const [token, setToken] = React.useState(null);
    const [users, setUsers] = React.useState(null);

    _retrieveToken = async () => {
        try {
            const token = await AsyncStorage.getItem('userToken');
            setToken(token);
        } catch (error) {
            Alert.alert("SESIÓN FINALIZADA");
        }
    };

    _retrieveToken();

    const requestOptions = {
        method: 'GET',
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'Bearer ' + token,
        },
    };

    fetch(`${baseUrl}/user/top`, requestOptions)
        .then((response) => response.json())
        .then(data => {
            if (data == undefined) {
                Alert.alert(
                    "Usuario inválido",
                    "el usuario no existe, o la contraseña o usuario son incorrectas ¿Estás seguro de que tienes cuenta?"
                );
            }
            console.log(data);
            setUsers(data);
        });

    return (
        <Leaderboard
            data={users}
            sortBy='highScore'
            labelBy='userName'
            icon='icon' />
    );
}

export default LeaderBoardScreen;

It starts sending GET to my back end in a infinite loop

2

Answers


  1. Try importing useEffect from React perhaps instead of where you have imported it from.

    Login or Signup to reply.
  2. That’s because fetch and get token are being called on every render, you should move the function call inside a useEffect, (Or React Query useQuery if you want a 3rd party library)

    The following code gets the token after the first render and then runs the fetches whenever the token changes

    
    
    const requestOptions = (token) => ({
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + token,
            },
        });
    
    const LeaderBoardScreen = ({ navigation }) => {
        const baseUrl = Constants.manifest.extra.backend_url;
        const [token, setToken] = React.useState(null);
        const [users, setUsers] = React.useState(null);
    
        _retrieveToken = useCallback(async () => {
            try {
                const token = await AsyncStorage.getItem('userToken');
                setToken(token)
            } catch (error) {
                Alert.alert("SESIÓN FINALIZADA");
            }
        },[])
    
    useEffect(()=>{
    _retrieveToken()
    },[_retrieveToken])
    
    
    
    useEffect(()=>{
        if(!!token){
        fetch(`${baseUrl}/user/top`, requestOptions(token))
            .then((response) => response.json())
            .then(data => {
                if (data == undefined) {
                    Alert.alert(
                        "Usuario inválido",
                        "el usuario no existe, o la contraseña o usuario son incorrectas ¿Estás seguro de que tienes cuenta?"
                    );
                }
                console.log(data);
                setUsers(data);
            })
        }
    },[token])
    
        return (
            <Leaderboard
                data={users}
                sortBy='highScore'
                labelBy='userName'
                icon='icon' />
        );
    }
    
    export default LeaderBoardScreen;
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search