3 votes

Appel de l'écran précédent lors de la navigation vers un nouvel écran dans React Native

J'ai exactement le même problème que celui décrit aquí . Lorsque vous naviguez entre les écrans à l'aide d'onglets ou d'un tiroir, chaque écran est rechargé, ce qui pose des problèmes à mon application.

J'ai essayé de suivre certaines des recommandations données dans le fil de discussion, mais je ne peux pas l'appliquer avec mon code. Par exemple :

Pour moi, la solution était d'imbriquer les navigateurs en tant qu'enfant du composant écran et de ne pas insérer le navigateur dans la propriété du composant.

Enveloppez-le dans le niveau supérieur du fichier et affectez-le à une variable, puis utilisez cette variable dans votre composant.

Mon tiroir est composé de 4 raccourcis vers 4 écrans (Accueil, Historique, Groupes, Paramètres). Les trois premiers sont également disponibles depuis l'écran d'accueil dans des onglets inférieurs.

Voici mon code : Navigation.js

import React from "react";
import { TouchableOpacity } from "react-native";
import { NavigationContainer} from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { createDrawerNavigator } from "@react-navigation/drawer";

import { Entypo } from "@expo/vector-icons";

import Settings from "../screens/Settings";
import Loading from "../screens/Loading";
import AddGroup from "../screens/AddGroup";
import GroupList from "../screens/GroupList";

import Home from "../screens/Home";
import Groups from "../screens/Groups";
import History from "../screens/History";

const HomeStack = createStackNavigator();
const HomeStackScreen = ({ route }) => (
  <HomeStack.Navigator}>
    <HomeStack.Screen
      name={route.name}
      component={Home}
    />
  </HomeStack.Navigator>
);

const HistoryStack = createStackNavigator();
const HistoryStackScreen = ({ route }) => (
  <HistoryStack.Navigator>
    <HistoryStack.Screen
      name={route.name}
      component={History}
    />
  </HistoryStack.Navigator>
);

const GroupsStack = createStackNavigator();
const GroupsStackScreen = ({ route }) => (
  <GroupsStack.Navigator>
    <GroupsStack.Screen
      name={route.name}
      component={Groups}
    />
  </GroupsStack.Navigator>
);

const AppTabs = createBottomTabNavigator();
const bottomTabsScreen = ({ route }) => (
  <AppTabs.Navigator>
    <AppTabs.Screen
      name="Home"
      component={HomeStackScreen}
    />
    <AppTabs.Screen
      name="History"
      component={HistoryStackScreen}
    />

    <AppTabs.Screen
      name="Groups"
      component={GroupsStackScreen}
    />
  </AppTabs.Navigator>
);

const AppDrawer = createDrawerNavigator();
const AppDrawerScreen = ({ navigation }) => (
  <AppDrawer.Navigator>
    <AppDrawer.Screen name="Home" component={bottomTabsScreen} />

    <AppDrawer.Screen name="History" component={HistoryStackScreen} />

    <AppDrawer.Screen name="Groups" component={GroupsStackScreen} />

    <AppDrawer.Screen name="Settings" component={Settings} />
  </AppDrawer.Navigator>
);

const RootStack = createStackNavigator();
const RootStackScreen = () => {
  const [isLoading, setIsLoading] = React.useState(true);

  React.useEffect(() => {
    setTimeout(() => {
      setIsLoading(!isLoading);
    }, 500);
  }, []);

  return (
    <RootStack.Navigator mode="modal">
      {isLoading ? (
        <RootStack.Screen name="Loading" component={Loading} />
      ) : (
        <RootStack.Screen
          name="AppDrawerScreen"
          component={AppDrawerScreen}
        />
      )}
      <RootStack.Screen
        name="AddGroup"
        component={AddGroup}
        options={modalOptionStyle}
      />

      <RootStack.Screen
        name="GroupList"
        component={GroupList}
        options={({ navigation }) => ({
          headerTitle: "Select an existing group",
        })}
      />
    </RootStack.Navigator>
  );
};

export default () => {
  return (
    <NavigationContainer>
      <RootStackScreen />
    </NavigationContainer>
  );
};

index.js :

import React from "react";
import Navigation from "./config/Navigation";
import { ConversionContextProvider } from "./util/ConversionContext";

export default () => (
  <ConversionContextProvider>
    <Navigation />
  </ConversionContextProvider>
);

Code final fonctionnel après avoir suivi x00 recommandations :

useEffect(() => {
  if (isFocusedGroups) setLoading(true);
  const unsubscribe = navigation.addListener("focus", () => {
    loadFlatlist("groups")
      .then()
      .catch((error) => console.error(error))
      .finally(() => {
        setLoading(false);
      });
  });
  return unsubscribe;
}, [navigation, isFocusedGroups]);

2voto

x00 Points 11008

Formez votre repo :

...
import { useIsFocused } from "@react-navigation/native";
...
const History = ({ navigation }) => {
  ...
  const isFocusedHistory = useIsFocused();
  ...
  useEffect(() => {
    ...
    loadFlatlist("savedRuns")
    ...
  }, [isFocusedHistory]);
  ...
}

chaque fois qu'un utilisateur ouvre o ferme l'onglet isFocusedHistory change, le composant correspondant se transforme et les effets se déclenchent.

Je n'ai pas lu toute l'application que vous avez écrite et je n'ai pas essayé de comprendre quel est le comportement souhaité, donc je ne peux pas dire exactement comment vous devez le changer. Mais c'est la cause première de votre problème.

Vous devriez probablement abandonner l'idée de récupérer les données sur le commutateur à onglets. Ce n'est pas une bonne idée de toute façon.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X