简体   繁体   中英

Call api before first render in functional component in React.js

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?

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.

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.

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM