简体   繁体   中英

React: Await for API fetch and LocalStorage set before render children components

I have the following app entry component:

  React.useEffect(() => {
    const fetchData = async () => {
      try {
        const libraries: unknown[] = await sendRequest('/libraries');
        const softwareComponents: unknown[] = await sendRequest('/softwareComponents');

        localStorage.setItem('libraries', JSON.stringify(arraySetup(libraries, 'libraries')));
        localStorage.setItem('softwareComponents', JSON.stringify(arraySetup(softwareComponents, 'software-components')));
      } catch (err) {
        console.error(err);
      }
    };
    isAuthenticated() && fetchData();
  }, []);

I am fetching Arrays from two endpoints and then set the result in the Local Storage, so I can read from it in other components.

A child component is using the data like this:

  const [data, setData] = React.useState<Array<any>>([]);

  React.useEffect(() => {
    const libraries = getLocalStorageItem('libraries');
    const softwareComponents = getLocalStorageItem('softwareComponents');
    const condition = libraries && softwareComponents;

    if (condition) {
      setData([...libraries, ...softwareComponents]);
    }
  }, []);

  const getDataLength = (category: string) => {
    return (data || []).filter((item: any) => item.category === category).length;
  };

  return (
    <React.Fragment>
      <OwcGrid item xs={12} s={4}>

        <LibrariesCard numberOfElements={getDataLength('libraries')} /> // rendering here the length of the localStorage item.

      </OwcGrid>

The following bug now exists:

Opening the app for the first time, the API is called and the localstorage is set.

But the child components that are using localStorage are rendered at the same time, so if (condition) setData([...libraries, ...softwareComponents]); is never met and the numberOfElements prop is always empty at the first time.

Only at the second refresh, localStorage is in place and I can count the elements out from it and render it.

Can somebody give me a hint to wait for localStorage.setItem in the App.layout or if I can wait and check in the child components as long as the storage is set and then render again?

Do you have to use local storage? You could solve your problem by using context api, where you can store all required values and use them in any component that you need to. If you have to use local storage, you can manage it from context.

Please checkout documentation for context: https://reactjs.org/docs/context.html

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