Изменение состояния сбрасывает навигацию

#reactjs #react-native #react-navigation

#reactjs #реагировать — родной #реагировать-навигация

Вопрос:

Я использую Firestore с приложением React Native. Я получаю исходные данные и прослушиваю изменения в режиме реального App.js времени. Мой код навигации React также находится на App.js . Мне нужно передать данные из Firestore в два компонента, Details и Countdown . Эти компоненты находятся в разных стеках навигации. Когда выполняется обновление Firestore Details , происходит обновление состояния App.js , заставляющее пользователя вернуться на главный экран.

Как я могу предотвратить это?

App.js

 export default function App() {
  const [user, setUser] = useState();
  const [countdownGames, setCountdownGames] = useState([]);

  useEffect(() => {
    const subscriber = auth().onAuthStateChanged((user) => {
      if (user) {
        setUser(user);
      }
    });
    return subscriber;
  }, []);

  useEffect(() => {
    const gameSubscription = firestore().collection("games").where("owner", "==", user.uid).onSnapshot(querySnapshot => {
      let tempMedia = []
      querySnapshot.docs.forEach(doc => {
        tempMedia.push(doc.data());
      });
      // State change here is forcing user back to home page
      setCountdownGames(tempMedia);
    }, error => console.log(error));
    return () => {
      gameSubscription();
    };
  }, [user]);

  const HomeStack = createStackNavigator();
  function HomeStackScreen() {
    return <HomeStack.Navigator>
      <HomeStack.Screen name="Find" component={Search} />
      <HomeStack.Screen name="Details" component={Details} initialParams={{ uid: user?.uid, games: countdownGames }} />
    </HomeStack.Navigator>
  }

  const CountdownStack = createStackNavigator();
  function CountdownStackScreen() {
    return <CountdownStack.Navigator>
      <CountdownStack.Screen name="Countdown" component={Countdown} initialParams={{ uid: user?.uid, games: countdownGames }} />
    </CountdownStack.Navigator>
  }

  const Tab = createBottomTabNavigator();
  function TabNavigation() {
    return <Tab.Navigator>
      <Tab.Screen name="Find" component={HomeStackScreen} />
      <Tab.Screen name="Countdown" component={CountdownStackScreen} />
    </Tab.Navigator>
  }

  const Stack = createStackNavigator();
  return <NavigationContainer>
    <StatusBar />
    <Stack.Navigator>
      <Stack.Screen name="Home" component={TabNavigation} />
    </Stack.Navigator>
  </NavigationContainer>
}
  

Комментарии:

1. Первый вариант, я бы посоветовал вам использовать deepcompareeffect ( github.com/kentcdodds/use-deep-compare-effect ) вместо useEffect, поскольку user является объектом.

Ответ №1:

Проблема в том, что вы создаете компоненты React внутри компонентов React. Вы никогда не должны этого делать. Определите все ваши компоненты на верхнем уровне файла.

Вместо:

 export default function App() {
  // Whatever

  const HomeStack = createStackNavigator();
  function HomeStackScreen() {
    // Whatever
  }
}
  

Сделать:

 const HomeStack = createStackNavigator();

function HomeStackScreen() {
  // Whatever
}

export default function App() {
  // Whatever
}
  

Дополнительная информация https://reactnavigation.org/docs/troubleshooting/#screens-are-unmountingremounting-during-navigation