Call api before first render in functional component in React.js
Asked Answered
I

5

7

If I want to call API after the first rendering of component, I know we have useEffect hook to call the API method. (I am talking about functional components only. No class component).

Is there any way, I can call the API before my component renders the first time.

The reason for this question is, If some UI part is dependent on API, I do not want to show any incomplete information to the user on the first render also, which will be changed once I get the data from API. This seems to be a bad experience with UI.

Edit: I got a couple of advice to use useLayoutEffect or any consumable flag to check if it is rendered or not. I have checked useLayoutEffect does not work, and by using the consumable flag, we are increasing the complexity only.

Do we have any better way for this?

Iconium answered 20/4, 2020 at 12:16 Comment(1)
Since before and after render are milliseconds apart then how do you think before render will make a difference to after render? In both cases you have to render something (like loading).Ultraconservative
W
3

I think useLayoutEffect can be used for something like this, by passing in an empty array as second argument. useLayoutEffect(() => {...}, []);

Updates scheduled inside useLayoutEffect will be flushed synchronously, before the browser has a chance to paint.

Although you can always fetch the data in the parent component and pass it as props. Or - if you don't mind it being an experimental feature for now - React Suspense is trying to solve this exact problem.

Windlass answered 20/4, 2020 at 12:25 Comment(6)
" before the browser has a chance to paint.", but not before component renderedGuthry
@Guthry that's true, I edited my answer to provide alternative methodsWindlass
@Nimishgoel You are correct. However, there is no built-in hook for this. Even componentWillMount is deprecated. You can write a custom hook like this one: https://mcmap.net/q/80686/-how-to-use-componentwillmount-in-react-hooks, or use one of the 2 alternate optionsWindlass
@Guthry what does it mean for a component to render? I thought it was rendered when it was rasterized by the GPU and painted on the screenOverlord
@duhaime, I think that the "render" in the context of the react can be considered a returning from the component (render function) updated part of the virtual DOM, goes right?Guthry
@Guthry yes I think you're right! I was underthinking the situation :/Overlord
Z
3

You can have a spinner or loading component be rendered first conditionally (isLoading for example):

if(isLoading) return <Spinner />

and have the api call set (isLoading) to false on status 200 for example.

Zwieback answered 26/6, 2022 at 10:1 Comment(1)
This is what you will find in most prod code. Simple and does the job.Strainer
G
0

There are no correct ways to make API call before component rendered from the same component.

You may preferred make API call in parent component and render presentation component when and only when have consumable data.

Another workaround for such case is keep consumable flag inside component, make request inside useEffect, render nothing or some kind loader and render something only when request completed with success.

Guthry answered 20/4, 2020 at 12:42 Comment(0)
C
0

on calling api it is not responding exact on its first render but giving exact response when it's being hit second time

Charlottcharlotta answered 25/4, 2022 at 7:0 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Armanda
G
0

Just came across something, which may help someone in future. So we can use some library but the specific one I would mention here is React Query

React query does exactly what we are trying to achieve, the hooks like useQuery fetch data as soon as rendering starts so you don’t have to wait until react loads the entire component as follows

// with react query
const { status, data, error, isFetching } = useQuery(
  ['data'],
  async () => {
    const data = await (
      await fetch(`${API_BASE_URL}/data`)
    ).json()
    return data
  }
)


// without react query
useEffect(() => {
  try {
    setLoading(true)(async () => {
      const data = await (await fetch(`${API_BASE_URL}/data`)).json();
      setData(data);
    })();
  } catch (error) {
    setError(error);
  } finally {
    setLoading(false);
  }
}, []);

Here is the article link if you want to read

Geisler answered 6/10, 2022 at 9:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.