Search code examples
javascriptreactjsreact-nativeactivity-indicator

Show activity indicator while navigating through screens in React Native


I have a file called ScreenOne.js. My goal is to show an activity indicator for three seconds while I navigate from ScreenOne to ScreenTwo. So the flow would be: ScreenOne -> Activity indicator (display for three seconds) -> ScreenTwo. This is what I would like to show up:

<ActivityIndicator color={blue} size="large" />

I already have tried several ways and the ScreenOne file contains the startLoading function for the indicator. I would really appreciate your help for this one. This is the ScreenOne file:

const ScreenOne = () => {
  const navigation = useNavigation();

  const navigateTo = () => {
    navigation.navigate('ScreenTwo')
  }

  const [loading, setLoading] = useState(false);

  const startLoading = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
    }, 3000);
  };

  return (
    <ScreenContainer>
      <Header style={styles.header} >
        <Text style={styles.textHeader} >ScreenOne</Text>
      </Header>
      <Text style={styles.message} >This is the ScreenOne</Text>
      <Button rounded buttonText='Go to ScreenTwo' textColor={colors.white} onPress={navigateTo} />
    </ScreenContainer>
  )
}

export default ScreenOne

Solution

  • I think you want something like this

    Working Example Here

    import * as React from 'react';
    import { Button, View, ActivityIndicator, Text } from 'react-native';
    import { NavigationContainer } from '@react-navigation/native';
    import { createStackNavigator } from '@react-navigation/stack';
    
    function ScreenOne({ navigation }) {
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>This is ScreenOne</Text>
          <Button
            title="Go to ScreenTwo"
            onPress={() => navigation.navigate('ScreenTwo')}
          />
        </View>
      );
    }
    
    function ScreenTwo({ navigation }) {
      const [Loading, SetLoading] = React.useState(true);
    
      React.useEffect(() => {
        const unsubscribe = navigation.addListener('focus', () => {
          SetLoading(true);
          setTimeout(() => {
            SetLoading(false);
          }, 3000);
        });
    
        return unsubscribe;
      }, [navigation]);
    
      if (Loading) {
        return (
          <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <ActivityIndicator color={'blue'} size="large" />
          </View>
        );
      }
    
      return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
          <Text>This is ScreenTwo</Text>
          <Button title="Go back" onPress={() => navigation.goBack()} />
        </View>
      );
    }
    
    const Stack = createStackNavigator();
    
    function MyStack() {
      return (
        <Stack.Navigator screenOptions={{ headerShown: false }}>
          <Stack.Screen name="ScreenOne" component={ScreenOne} />
          <Stack.Screen name="ScreenTwo" component={ScreenTwo} />
        </Stack.Navigator>
      );
    }
    
    export default function App() {
      return (
        <NavigationContainer>
          <MyStack />
        </NavigationContainer>
      );
    }