Search code examples
javascriptreact-nativehookuse-effectactivity-indicator

How do you make a React Native ActivityIndicator appear after an onPress to show something is loading?


When navigating between Screen 1 and Screen 2, the user presses a button. After pressing, it can sometimes take a few seconds to before the app navigates them to the next screen, so it does not look like anything is happening. How would I go about making an activity indicator appear until they are navigated to the next page? I have gotten an ActivityIndicator to work while other things load, but that's not until they navigate to that page.

Below is my code that launches the activity indicator while the maps page is loading:

  const [isLoading, setIsLoading] = useState(true)

  const renderLoading = () =>  {
        if (isLoading) {
            return (         
            <View style = {{justifyContent: 'center', backgroundColor: '#d3d3d3', textAlign: 'center', height: height, width: width}}>
            <ActivityIndicator
            color = 'black'
            size = 'large'
            animated = {false}
          />
          <Text style = {[ styles.text, {textAlign: 'center'}]}>{i18n.t('loading')}</Text>
          </View>

            );
        }else {
            return null;
        }
    }


     <View style = {styles.container}>
        {renderLoading}
        ....
     </View>

Solution

  • If you have control over the map screen I would recommend putting the spinner in that component. In other words, if you are doing the rendering, you will be able to determine at what stage you want to show the map instead of the spinner:

    function IRenderTheMap(): ReactElement {
      const [isLoading, setIsLoading] = useState(true);
    
      useEffect(() => {
        // Load/preper/render map data, whatever
        // ..
    
        // Somehow determine that enough content has loaded
        if (isReadyToShow) setLoading(false);
      }, []);
    
      if (isLoading) return <Spinner />;
      // otherwise return your result
    }
    

    If you are using some "third-party" component that renders the map, it hopefully has some sort of callback prop that tells you if it finished loading. So check the docs and look for that.:

    function IJustContainTheMap(): ReactElement {
      const [isLoading, setIsLoading] = useState(true);
      
      return (
        <View>
          {isLoading && (
            // Absolutely position the spinner so it's on top of the map
            <OverlaySpinner />
          )}
          <Map onLoadEnd={() => setIsLoading(false)} />
        </View>
      );
    }
    

    If the component you are using to render the map does not provide that... well I think you are out of luck. Probably best off bugging the library author to either add an "onLoadEnd" prop (or similar) or render a spinner themselves.

    Or one may always for the library and add a feature themselves, but that's most of the time quite hard.