React state 업데이트 불가
마운트되지 않은 컴포넌트의 상태값
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. in SwipeUpDownModal (at Bank.js:175)
Toast 만들기
react-native-easy-toast
뒤로가기를 두번 눌러 앱 종료하기 위해, 뒤로가기를 한번 눌렀을 때 앱종료 안내 토스트를 띄우려고 라이브러리를 설치했다.
사용법은 위 문서와 아래 링크를 참고했다.
https://jw910911.tistory.com/96
import Toast, {DURATION} from 'react-native-easy-toast';
const Home = ({navigation}) => {
const toast = useRef();
let backPressCount = 0;
const exit = () => {
if (backPressCount < 1) {
toast.current.show('앱을 종료하려면 한 번 더 눌러주세요!',DURATION.LENGTH_SHORT);
Toast.show('앱을 종료하려면 한 번 더 눌러주세요!', 100);
backPressCount++;
} else {
BackHandler.exitApp();
}
setTimeout(() => {
backPressCount = 0;
}, 2000);
};
useFocusEffect(
useCallback(() => {
BackHandler.addEventListener('hardwareBackPress', exit);
return () => BackHandler.removeEventListener('hardwareBackPress', exit);
}, []),
);
return(
...
<Toast ref={toast} />
...
);
};
근데 작동하지 않음...
react-native-simple-toast
import Toast from 'react-native-simple-toast';
Toast.show('앱을 종료하려면 한 번 더 눌러주세요!', 100);
다른 라이브러리를 설치해봤다. 한 줄만에 작동한다.
[Blocker] 뒤로 가기 꼬임
스택이 쌓여있을 때 이전 스택으로 돌아가는 기능(뒤로 가기)은 goBack()과 pop()이 있는데, pop()은 stack navigator에서만 쓸 수 있다고 한다. tab navigator에서는 쓸 수 없다는 뜻. 이외에도 둘이 완전히 같은 기능이라고 할 수는 없는 것 같다. 하지만 대략적으로 같은 기능을 한다.
그런데 뒤로 가기가 이상하게 동작하는 문제가 생겼다. A -> B -> C -> D -> B 로 스크린을 이동했을 때 마지막 B 화면에서 뒤로 가기를 했는데 D가 아니라 A로 가는 것이다. 암만 찾아봐도 원인을 못 찾겠다. 같은 스크린에 다시 도착하면 그 사이의 stack history가 사라지나 싶다가도, A -> X -> B -> Y -> A -> B 로 스크린을 이동했을 때는 뒤로 가기를 하면 X가 아니라 A로 잘 이동한다.
여러 번 사용되는 비밀번호 확인 Screen 쪼개기
1. 하나의 screen으로 처리
const PwVerify = ({route, navigation}) => {
const {idText, isLogin, isRemitting} = route.params;
const [enteredPin, setEnteredPin] = useState('');
...
useEffect(() => {
if (enteredPin.length === 6) {
const realNum = fixNum(enteredPin); // 랜덤으로 배열된 키패드에 맞게 실제 입력 숫자로 변환
// 송금 전 비밀번호 확인
if (isRemitting) {
remitFetch(realNum);
return;
}
// 로그인 시 비밀번호 확인
if (isLogin) {
loginFetch(realNum);
return;
}
// 회원가입 시 비밀번호 확인
if (!pwText) {
// 첫번째 비밀번호 입력
} else if (pwText !== realNum) {
// 비밀번호 재확인 입력 불일치
} else {
// 비밀번호 재확인 입력 일치
}
}
}, [enteredPin]);
const Remit = ({navigation}) => {
const goNext = () => {
navigation.navigate('PwVerify', {isRemitting: true});
};
...
}
비밀번호를 입력할 수 있는 하나의 화면을 만들어놓고 필요할 때마다 이 screen으로 navigate해서 어떤 상황이냐에 따라 각각 다른 동작을 취하도록 했다. 각각 화면에 도달하는 경로에 따라 개별적인 stack history를 갖는다. 그래서 뒤로 가기를 하면 그때그때 경로에 따라 직전에 있던 화면으로 다르게 이동해야 한다.
그런데 앞에 서술한 블로커의 문제가 있었다. 로그인할 때 Login -> PwVerify 흐름으로 해당 화면에 navigate한 후, 다른 화면들을 거쳐 송금 과정에서(Home -> Bank -> Amount -> Remit -> PwVerify) 다시 PwVerify 스크린에 도착한다. 이 상황에서는 뒤로 가기를 하면 로그인 흐름으로 해당 화면에 도착한 상황인 것처럼 Login 스크린으로 이동한다. 왠지 모르겠지만 stack이 꼬이는 것 같다. 이상한 점은 회원가입을 한 뒤 로그인을 할 때도 마찬가지로 PwVerify 스크린에 다시 navigate되지만 뒤로 가기를 했을 때 이상한 화면으로 이동하지 않는다. 어쨌건 뒤로 가기 버튼이 눌렸을 때 일어나는 동작을 고쳐서 해결해보려고 했지만 실패해서 다른 방법을 찾기로 했다.
2. "화면을 통째로 컴포넌트처럼 렌더링" or "화면으로 navigate"
회원가입 흐름이나 로그인 흐름에서는 id 확인 -> pw 확인으로 각 화면이 분리되어야 하므로 PwVerify를 하나의 screen으로 만들어둔 것이다. 그런데 송금하기 전 비밀번호 확인 상황의 경우, 송금하기(Remit) 화면에서 PwVerify 화면을 아예 import하여 컴포넌트처럼 렌더링함으로써 보여주어도 될 것 같아서 해보았다.
const PwVerify = ({route, navigation}) => {
const {idText, isLogin, isRemitting} = route.params;
...
}
import PwVerify from './PwVerify';
const Remit = ({navigation}) => {
const [isConfirmed, setIsConfirmed] = useState(false);
const goNext = () => {
setIsConfirmed(true);
};
return isConfirmed ? (
<PwVerify route={{params: {isRemitting: true}}} navigation={navigation} />
) : (
<Container> ... </Container>
);
};
PwVerify는 screen으로써 navigate되기도 하지만, Remit.js에서는 컴포넌트로써 import되어 렌더링된다. 이때는 stack이 꼬이지 않아, 뒤로 가기에서 발생하던 문제가 해결된다.
하지만 PwVerify가 navigate된 경우에 사용할 변수를 route.params로 받고 있었는데 PwVerify를 컴포넌트로써 렌더링할 때는 해당 props가 없어서 에러가 난다. 그래서 navigation은 물론 route.params의 모양을 한 객체를 임의로 전달했다. 야매로 해결은 되지만 좋은 방법은 아니다.
3. PwCheck 컴포넌트 분리
공부할 것
'TIL' 카테고리의 다른 글
[TIL-171] Session (0) | 2022.04.30 |
---|---|
[TIL-170] React Native (0) | 2022.04.20 |
[TIL-168] React Native : 안드로이드 BackHandler 앱 종료, Promise로 fetch 동기 처리, 세션 (0) | 2022.04.18 |
[TIL-167] React Native (0) | 2022.04.15 |
[TIL-166] React Native (0) | 2022.04.14 |