본문 바로가기
프로젝트 답지

[Dap JI ] expo 스텍관리문제

by 띠리에이터 2024. 11. 21.
1. 문제

 

프로필 페이지에서 router.push로 세팅 페이지로 이동

=> 이때 push때문에 프로필 페이지에 대한 스택이 쌓임

세팅 페이징세ㅓ 로그아웃 버튼 누른 후 isSuccess면 router.replace('/') 로 이동

루트페이지 이동 후 뒤로가기 드래그 하면 다시 이전 프로필 페이지로 이동됨

하지만 유저 id가 없어 데이터는 캐시된 데이터 외에는 데이터를 불러올 수 없음

굉장히 굉장히 거슬림

 

 

2. 원인

아마 profile에서 push때문에 쌓인 스택 때문에 뒤로가게되는거라 생각

replace를 사용해도 이전 스택만 제거할뿐 전체 스택을 제거하진 않음

 

3. 해결 방법

 

1. @react-navigation/native 사용해야할듯

 

리액트 네이티브에서 많이 사용하는 라우팅 라이브러리 

 

https://www.npmjs.com/package/@react-navigation/native

npm i @react-navigation/native

 

import { useNavigation, CommonActions } from '@react-navigation/native';

const navigation = useNavigation();

if (isSuccess) {
  navigation.reset({
    index: 0,
    routes: [{ name: 'index' }], 
  });
  return null;
}

1. '@react-navigation/native 에서 useNavigation 과 CommonActions 를 임포트함

2. useNavigation 객체 초기화

3. navigation.reset()은 현재의 네비게이션 상태를 새로운 상태로 재설정합니다. 즉, 기존의 네비게이션 스택(화면 히스토리)을 완전히 제거하고, 새로운 스택으로 대체한다. 

4.  index를 0으로 설정하고 하나의 라우트(홈 페이지)를 제공 즉 이전 스택을 초기화 하는 것 같음

index: 0: 이 값은 routes 배열에서 어떤 라우트가 현재 활성화될지를 결정합니다. 새로운 네비게이션 스택에서 현재 활성화될 화면의 위치

 

5. routes: [{ name: 'index' }],  는 홈 라우트의 이름과 일치해야 함 

 


바로 해결 ㅠㅠ 라이브러리 최고 

 


2차 24.11.28

expo sdk업데이트 한 이후로 갑자기 안됨, 

react-navigation/native 는 NavigationContainer를 설정 안하면 사용할 수 없다고 나옴,,,

완벽한 스택 관리를 위해 react-navigation/native 로 리팩토링 해야겠음, 

expo -router 기존에 next.js에서 사용하던 useRouter과 같아서 편하게 사용했는데 사용자 경험상 스택 관리가 잘 안되는 큰 단점, replace사용해도 그 이전 스택이 남아있어서 뭔가 앱으로서의 가치가 좀 떨어지는 것 같다.


import { createNativeStackNavigator } from "@react-navigation/native-stack";
import HomeScreen from ".";
import SignupScreen from "./screens/auth/SignupScreen";

const Stack = createNativeStackNavigator();

export default function RooutLayout() {
  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="SignupScreen" component={SignupScreen} />
      </Stack.Navigator>
    </NavigationContainer>

루트 레이아웃에 navigationContainer 선언, 해당 스크린 name과 컴포넌트 추가, 

import React from "react";
import { View, Text, Button } from "react-native";

export default function HomeScreen({ navigation }: any) {
  return (
    <View
      style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
      }}
    >
      <Text>Welcome to the Home Screen!</Text>
      <Button
        title="Go to SignupScreen"
        onPress={() => navigation.navigate("SignupScreen")}
      />
    </View>
  );
}

navigation.navigate 안에 이동한 name 담아주기, 클릭하면 

에러 발생 , NavigationContainer가 중첩된다고 나옴, 

이유는 expo-router에서 자체적으로 NavigationContainer를 생성하기 때문이라고 함, 

따라서 expo-router 삭제 해야함, 같이 못씀, 

 

ㅎ므...흠..

 


3차. 11/29

expo-router는 죄가 없다.

하 .. 공식문서 최고.. 안읽은 내 잘못... 공식문서 읽는 습관을 기르자

 

expo-router에는 내가 아는 것보다 더 다양한 기능이 있었음. ....

그증 dismiss와 dismissAll이 나한테 필요했던것, 

 

dismiss
  • 현재 화면에서 특정 개수만큼 스택의 화면을 제거하느 메서드네요.
  • 현재 화면을 기준으로 count만큼 이전 화면으로 돌아감

[Screen A] -> [Screen B] -> [Screen C] -> [Screen D]

 

이런 스택 구조를 보고 현재 화면이 D라면 

 

  • router.dismiss(1) 호출 시 Screen C로 이동.
  • router.dismiss(2) 호출 시 Screen B로 이동.
  • router.dismiss(3) 호출 시 Screen A로 이동.

이런식으로 동작함, 

 

dismissAll()

 

  • 스택의 첫 번째 화면으로 돌아가는 동작 수행, 
  • 스택 내에서 모든 중간 화면을 제거하고 첫 화면만 남김
[Screen A] -> [Screen B] -> [Screen C] -> [Screen D]

 

이런 스택구조에서 현재 화면이 D라면

  • router.dismissAll() 호출 시 A 화면만 남게됨. 

관련된 스택 다시 확인해보기