🔍 문제 상황
RN에서 TextInput에 뭔가 입력하고 키보드 열린 상태에서
바로 아래에 있는 버튼을 누르면 키보드는 내려가는데... 정작 onPress
이벤트는 안 먹음
예를 들어 이렇게 돼 있으면:
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
<View>
<TextInput />
<Button title="확인" onPress={handleSubmit} />
</View>
</TouchableWithoutFeedback>
여기서 버튼을 눌러도 handleSubmit()
은 실행 안 됨.
이유는 터치 이벤트가 키보드 닫는 데만 쓰이고 버튼까지 도달하지 않기 때문.
💡 해결 방법: 구조 변경하기
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : undefined}
style={{ flex: 1 }}
>
<TouchableWithoutFeedback onPress={Keyboard.dismiss} accessible={false}>
<ScrollView
keyboardShouldPersistTaps="handled"
contentContainerStyle={{ flexGrow: 1 }}
>
<TextInput placeholder="이름" />
<Button title="확인" onPress={handleSubmit} />
</ScrollView>
</TouchableWithoutFeedback>
</KeyboardAvoidingView>
이 구조를 쓰면 대부분의 경우 문제 없이 동작한다.
즉, 키보드 열린 상태에서도 버튼 터치 시:
키보드는 내려가고
버튼의
onPress
도 잘 호출됨
여기서 핵심은 두 가지:
keyboardShouldPersistTaps="handled"
를 꼭 넣을 것
→ 스크롤 영역 내 터치 이벤트가 무시되지 않도록 해줌TouchableWithoutFeedback
으로 감싸되Button
까지 너무 깊게 감싸지 말 것
→ 가능한 한 ScrollView 내부만 감싸는 게 좋음
🧠 팁: 중요한 액션이라면 Keyboard.dismiss()
를 명시적으로 넣어주기
위 구조로 잘 짜면 대부분 잘 되지만, 버튼 이벤트에 아래처럼 명시적으로 Keyboard.dismiss()
를 넣는 것이 더 안정적일 수 있다.
const handleSubmit = () => {
Keyboard.dismiss(); // 키보드를 확실히 내려주고
// 이후 로직 실행
};
아래와 같은 이유로
플랫폼/기기별로 간혹
keyboardShouldPersistTaps
가 예상대로 동작하지 않을 때도 있음alert
,toast
,modal
,navigation
등과 같이 키보드와 겹치면 어색한 UI가 나올 수 있음UX 관점에서 “버튼을 누르면 무조건 키보드가 내려가야 한다”는 게 확실하면 명시가 더 안전
✅ 마무리 정리
키보드가 열린 상태에서 버튼이 안 눌리는 건 구조 문제일 가능성이 높음
KeyboardAvoidingView
+TouchableWithoutFeedback
+ScrollView(keyboardShouldPersistTaps="handled")
조합으로 대부분 해결 가능하지만 정말 중요한 액션이라면
Keyboard.dismiss()
를 함수 안에 넣어서 명시적으로 처리하는 습관을 들이는 게 좋음
“구조로 해결하고, 명시는 안전장치처럼!”
두 가지 조합이면 대부분의 폼 입력 이슈는 막을 수 있다