0

I have no idea why, the first render shows an empty object and the second shows my data:

function RecipeList(props) {
    return (
        <div>
            {console.log(props.recipes)}
            {/*{props.recipes.hits.map(r => (*/}
            {/*    <Recipe initial="lb" title={r.recipe.label} date={'1 Hour Ago'}/>*/}
        </div>
    )
}

const RECIPES_URL = 'http://cors-anywhere.herokuapp.com/http://test-es.edamam.com/search?i?app_id=426&q=chicken&to=10'
export default function App() {
  const classes = useStyles();
  const [data, setData] = useState({});

    useEffect(() => {
        axios.get(RECIPES_URL)
            .then(res => {
                setData(res.data);
            })
            .catch(err => {
                console.log(err)
            })
    }, []);
  return (
    <div className={classes.root}>
      <NavBar/>
      <RecipeList recipes={data}/>
      <Footer/>
    </div>
  );
}

I don't know why and I have struggled here for over an hour (React newbie), so I must be missing something.

enter image description here

2
  • This is the correct behavior. You have an asynchronous request which when completes updates the state. This causes a rerender. The state is passed down as props to RecipeList, but it's initial state is an empty object, so will only include the data on the second render. Commented Apr 24, 2020 at 17:14
  • A good approach to dealing with this is rendering a 'Loading..' component whilst the data is being fetched / undifined, and then rendering RecipeList when it is not. Commented Apr 24, 2020 at 17:25

2 Answers 2

2

This is the expected behavior. The reason you see two console logs is because, the first time RecipeList is called with no data (empty object), and the second time when the data becomes available. If you would like to render it only when the data is available you could do something like {Object.keys(data).length > 0 && <RecipeList recipes={data}/>}. By the way this is called conditional rendering.

Sign up to request clarification or add additional context in comments.

Comments

1

This is perfectly normal, React will render your component first with no data. Then when your axios.get returns and update data, it will be rendered again with the new data

2 Comments

Is this so users see all the static data in the meanwhile until the dynamic data has been fetched?
It's just that your axios.get is asynchronous, so you will receive an answer in the future. And while you're waiting for axios to get back to you, then React is still doing its job: render your UI. Then later when data is updated, React knows that your UI depends on it, so it will render a second time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.