Expo Router의 Stack.Screen에서 header에 기능 트리거를 위한 TouchableOpacity 컴포넌트를 사용하려고 했다. 하지만 onPress는 트리거 되지 않았고, 화면에 표시는 되지만 반응을 하지 않는 상황이 발생했다.
혹시나 onPress에 할당된 함수가 잘못 되었을까 싶어 console.log로 테스트 해봤지만 소용 없었다.
더군다나 동적으로 header의 요소를 업데이트 해야 했기에, useLayoutEffect 훅을 사용해서 header에 요소를 준 상태였고 useLayoutEffect 자체가 문제의 원인일까도 싶었다.
useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<TouchableOpacity onPress={handleSubmit(onSubmit)}>
<CustomText style={{ fontSize: 16 }} weight="Bold">
완료
</CustomText>
</TouchableOpacity>
),
headerLeft: () => (
<TouchableOpacity
onPressIn={() => {
router.back();
clearPlace();
}}
>
<Feather name="chevron-left" size={24} color="#222" />
</TouchableOpacity>
),
});
}, [navigation]);
navigation의 setOptions를 사용해서 헤더의 각 요소를 구현했는데, @react-nativation/native에 기본으로 있는 네비게이션 제스처 핸들러가 headerLeft 영역 뿐만 아니라 헤더 전체 영역을 포함하기 때문에, 이게 터치 이벤트를 가로챈다고 한다.
https://reactnative.dev/docs/pressable
onPress는 터치가 시작되고, 터치한 상태에서 영역을 벗어나지 않고 손가락을 떼는 순간까지를 포함하며 이 과정까지 정상적이여만(=> 유효한 탭(valid tap)이라고 인식될 때만) 트리거 된다고 한다.
반면 onPressIn은 터치가 시작되는 즉시 발동한다.
onPress을 onPressIn으로 변경해 버그는 즉시 해결할 수 있었다.