Monica Maged Malaty
Monica Maged Malaty

Reputation: 13

Running into an infinite loop when using useEffect() in react-native

I have recently begun using react native and I'm building this mobile application using Expo. I am using useEffect() to be able to call a function inside it. All I want is to wait for the reponse of the API to finish completely before I display the result (which in this case is the connectionName variable). I gave the useEffect() function walletsas a second parameter because I want the API fetched again whenever wallets changes, but I seem to be running in an infinite loop even though wallets hasn't changed. Any help is much appreciated.

export default function LinksScreen() {

       const [wallets, setWallets] = React.useState([]);
       const [count, setCount] = React.useState(0);
       const [connectionName, setConnectionName] = React.useState("loading...");

       React.useEffect(() => {
          (async () => {
             fetchConnections();
          })();
       }, [wallets]);

       async function fetchConnections() {

          const res = await fetch('https://api.streetcred.id/custodian/v1/api/' + walletID + '/connections', {
             method: 'GET',
             headers: {
                Accept: 'application/json',
             },
          });
          res.json().then(res => setWallets(res)).then(setConnectionName(wallets[0].name))
       }

       return (
          <ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
             <OptionButton
                icon="md-school"
                label={connectionName}
                onPress={() => WebBrowser.openBrowserAsync('https://docs.expo.io')}
             />
          </ScrollView>
       );
    }

Upvotes: 1

Views: 394

Answers (2)

Agus Zubiaga
Agus Zubiaga

Reputation: 542

Your useEffect hook runs every time wallets changes, and it calls fetchConnections, which calls setWallets, which then triggers your useEffect hook because it changed wallets, and so on...

Pass an empty dependencies array to useEffect:

React.useEffect(() => {...}, [])

That will make it run only on mount.

If you still want to call fetchConnections whenever wallets changes, you shouldn't do it through an effect hook because you'll get the infinite loop you described. Instead, call fetchConnections manually whenever you call setWallets. You could make a function that does this for you:

const [wallets, setWallets] = useState([]);
const setWalletsAndFetch = (wallets) => {
  setWallets(wallets);
  fetchConnections(wallets);
} 

Upvotes: 1

Yoel
Yoel

Reputation: 7985

You listen to a change and then as it changes you change it over and over without stopping

 React.useEffect(() => {
          (async () => {
             fetchConnections();
          })();
       }, []);//remove wallets

Upvotes: 0

Related Questions