skip to Main Content

I’m building an app with React Native and having trouble showing the results from an API call.

function getRecipes() {
  const [recipes, setRecipes] = React.useState([]);

  axios.get('http://localhost:5000/api/v1/recipes')
    .then(response => {
      var data = response.data.map((recipe: Object) => recipe)
      setRecipes(data);
    }).catch(err => {
      console.log(err);
    });

  return recipes
};

export default function Recipes({ navigation }: Props) {
  const recipes = getRecipes();
  console.log(recipes)

  return (
      ...other code
      <View>
        {recipes}
      </View>
    </View>
  );
};

console.log(recipes)

console.log(recipes) returns the result of the API request over and over, I only need it once. How can I use the function getRecipes to return just one instance of the request?

2

Answers


  1. The problem you are experiencing stems from the fact that the getRecipes function is called each time the Recipes component is rendered; because axios.get is asynchronous, this means that rendering occurs before the API call is finished, which leads to multiple console.log(recipes) executions as the component re-renders.

    import React, { useState, useEffect } from 'react';
    
    export default function Recipes({ navigation }: Props) {
    
      const [recipes, setRecipes] = useState([]);
    
      useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await axios.get('http://localhost:5000/api/v1/recipes');
            const data = response.data.map((recipe: Object) => recipe);
            setRecipes(data);
          } catch (err) {
            console.log(err);
          }
        };
    
        fetchData();
    
      }, []);
    
      console.log(recipes)
    
      return (
          ...other code
          <View>
            {recipes}
          </View>
        </View>
      );
    };
    

    Here the recipes are stored in the component’s state using setRecipes, and are mapped over to render the components in the JSX. The useEffect hook is used to conduct the API call when the component mounts ([] as the dependency array guarantees it only runs once).

    Login or Signup to reply.
  2. Hope this will help you in get your recipe data render only once

    import { useState, useEffect } from "react";
    import axios from "axios";
    
    export default function Recipes({ navigation }: Props) {
        
        const [recipes, setRecipes] = React.useState([]); /* hooks are always inside functional tsx Component */
    
        function getRecipes() {
            axios.get('http://localhost:5000/api/v1/recipes')
                .then(response => {
                    var data = response.data.map((recipe: Object) => recipe)
                    setRecipes(data);
                }).catch(err => {
                    console.log(err);
                });
    
            return recipes
        };
        /* To Call funtions once after component we use useEffect hook */
        useEffect(() => {
            getRecipes()
        }, [])
        console.log(recipes)
    
        return (
            ...other code
            <View>
            { recipes.length > 0 && recipes }
            </View >
          </View >
        );
    };
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search