aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
SAVED POSTS
aedev.net
  • Trang chủ
  • AI
  • Mobile
  • Flutter
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
No Result
View All Result
aedev.net
No Result
View All Result
Minh hoạ form TextInput validation và keyboard trong React Native

React Native: tránh bàn phím che form với KeyboardAvoidingView và ScrollView

Suong Nguyen by Suong Nguyen
22/10/2026
in React Native
0
585
SHARES
3.2k
VIEWS
Summarize with ChatGPTShare to Facebook

Form hiển thị đẹp khi chưa nhập, nhưng ô mật khẩu hoặc nút gửi biến mất lúc bàn phím mở. Thêm một khoảng trống cố định có thể sửa được trên máy của bạn rồi lại hỏng trên màn hình nhỏ, font lớn hoặc một navigator có header khác.

Bài viết tập trung vào bố cục và thao tác bàn phím, dành cho người đã biết TextInput và state cơ bản. API được đối chiếu tài liệu React Native ngày 22/10/2026. Hành vi cần được kiểm tra cùng phiên bản React Native, cấu hình cửa sổ Android và navigation của dự án; không có một giá trị offset cố định đúng cho mọi màn hình.

Chia trách nhiệm cho từng lớp

KeyboardAvoidingView điều chỉnh bố cục khi bàn phím xuất hiện. ScrollView cung cấp vùng cuộn khi nội dung lớn hơn phần còn lại. keyboardShouldPersistTaps ảnh hưởng cách một lần chạm được chuyển tới phần tử con khi bàn phím đang mở.

Ba trách nhiệm này liên quan nhưng không thay thế nhau. Một form có thể tránh được bàn phím nhưng không cuộn vì parent thiếu chiều cao hữu hạn. Hoặc nút đã nhìn thấy nhưng lần chạm đầu chỉ đóng bàn phím, khiến người dùng tưởng nút không phản hồi.

Bố cục khởi đầu cho form ngắn

Ví dụ nhận callback onSubmit từ ứng dụng; không triển khai xác thực và không ghi credential ra log. Màn hình cha chịu trách nhiệm xử lý safe area và truyền offset phù hợp với vị trí thực của vùng form.

import React, {useState} from 'react';
import {
  KeyboardAvoidingView, Platform, Pressable,
  ScrollView, StyleSheet, Text, TextInput,
} from 'react-native';

type Props = {
  keyboardOffset?: number;
  onSubmit: (value: {email: string; password: string}) => void;
};

export function LoginForm({keyboardOffset = 0, onSubmit}: Props) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  return (
    <KeyboardAvoidingView
      style={styles.screen}
      behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
      keyboardVerticalOffset={keyboardOffset}>
      <ScrollView
        style={styles.screen}
        contentContainerStyle={styles.content}
        keyboardShouldPersistTaps="handled"
        keyboardDismissMode="on-drag">
        <Text>Email</Text>
        <TextInput
          accessibilityLabel="Email"
          style={styles.input}
          value={email}
          onChangeText={setEmail}
          autoCapitalize="none"
          autoCorrect={false}
          keyboardType="email-address"
        />
        <Text>Mật khẩu</Text>
        <TextInput
          accessibilityLabel="Mật khẩu"
          style={styles.input}
          value={password}
          onChangeText={setPassword}
          autoCapitalize="none"
          secureTextEntry
        />
        <Pressable
          accessibilityRole="button"
          style={styles.button}
          onPress={() => onSubmit({email, password})}>
          <Text style={styles.buttonLabel}>Đăng nhập</Text>
        </Pressable>
      </ScrollView>
    </KeyboardAvoidingView>
  );
}

const styles = StyleSheet.create({
  screen: {flex: 1},
  content: {flexGrow: 1, padding: 24, justifyContent: 'center'},
  input: {minHeight: 48, borderWidth: 1, padding: 12, marginBottom: 16},
  button: {minHeight: 48, padding: 12, backgroundColor: '#0369a1'},
  buttonLabel: {color: '#fff', textAlign: 'center'},
});

Các parent phía trên cũng phải có chiều cao hữu hạn hoặc truyền flex: 1 phù hợp. flexGrow của vùng nội dung cho phép form tận dụng khoảng trống, trong khi vẫn có khả năng cuộn nếu nội dung dài hơn viewport. Đừng đặt chiều cao cố định theo một thiết bị để ép form vừa màn hình.

Offset phải phản ánh bố cục thật

Theo tài liệu, keyboardVerticalOffset liên quan khoảng cách từ đầu màn hình tới view React Native. Header của navigator, safe area và cách màn hình cha đặt nội dung có thể tác động tới cấu hình cần dùng.

Hãy đo hoặc lấy thông tin bố cục từ lớp chịu trách nhiệm về header, rồi kiểm tra trên màn hình thực tế. Không cộng cùng một inset ở nhiều nơi. Nếu xuất hiện khoảng trắng lớn phía trên bàn phím, xem lần lượt header, padding, inset và cơ chế resize của cửa sổ thay vì giảm một con số ngẫu nhiên cho đến khi vừa mắt.

Ví dụ dùng padding trên iOS và height trên Android như điểm bắt đầu. Đó không phải bảo đảm rằng mọi app phải dùng cùng hai giá trị. Nếu hệ điều hành hoặc một lớp khác đã thay đổi kích thước viewport, cần kiểm tra tương tác để tránh bù khoảng trống hai lần.

Vì sao chọn handled cho thao tác chạm?

Khi bàn phím mở, hành vi mặc định của ScrollView có thể làm lần chạm ngoài ô nhập đóng bàn phím mà phần tử con không nhận lần chạm đó. handled cho phép phần tử con như nút xử lý tap theo quy tắc được tài liệu mô tả.

Đừng nhầm thuộc tính này với việc tự submit hoặc tự đóng bàn phím. Callback vẫn cần xử lý validation, trạng thái đang gửi và phản hồi lỗi. Ví dụ giữ phần đó ở ngoài để bạn tập trung kiểm tra bố cục mà không gắn mẫu đăng nhập vào một backend giả.

keyboardDismissMode="on-drag" cho phép thao tác kéo đóng bàn phím. Chế độ interactive là hành vi riêng iOS, nên không nên chọn nó rồi kỳ vọng Android hoạt động giống hệt. Nếu cần UX khác nhau giữa nền tảng, hãy cấu hình và ghi rõ mục tiêu kiểm tra.

Checklist kiểm tra trước khi đưa vào app

Thử form với màn hình nhỏ, font lớn, bàn phím email và bàn phím mật khẩu. Focus ô cuối, cuộn tới nút gửi, chạm nút khi bàn phím còn mở và đóng/mở bàn phím nhiều lần. Thử cả màn hình có header lẫn màn hình trình bày toàn màn hình nếu sản phẩm có hai kiểu đó.

Với form dài, kiểm tra riêng việc cuộn tới input đang focus; chỉ điều chỉnh kích thước view không tự chứng minh mọi input đều nằm đúng vị trí. Với màn hình nhiều lớp cuộn, hạn chế thêm ScrollView lồng nhau chỉ để che lỗi parent thiếu kích thước.

Ví dụ này chưa phải kết quả kiểm thử trên thiết bị cụ thể. Khi đánh giá, ghi lại phiên bản React Native, OS, cấu hình navigator và các bước tái hiện để team có thể kiểm tra cùng một tình huống.

Kết luận

Sửa form bị bàn phím che nên bắt đầu từ chiều cao parent, vùng cuộn và offset thực tế. Sau đó kiểm tra thao tác chạm và khác biệt nền tảng; cách này dễ duy trì hơn việc rải thêm padding cố định quanh từng ô nhập.

Nguồn tham khảo

  • React Native: KeyboardAvoidingView
  • React Native: ScrollView và keyboardShouldPersistTaps

Tags: FormKeyboardReact Native
SummarizeShare234
Suong Nguyen

Suong Nguyen

Related Stories

Minh hoạ FlatList hiển thị danh sách bài viết trong React Native

Tối ưu FlatList trong React Native: đo trước, chỉnh props sau

by Suong Nguyen
21/10/2026
0

Bắt đầu từ chi phí render item, key ổn định và kích thước hàng trước khi thay windowSize hoặc các tham số render của FlatList.

Minh họa ứng dụng React Native kết nối nhiều SDK như analytics, maps, authentication, payment và push notification

Tích hợp SDK trong React Native: quy trình thực chiến từ cài đặt đến release

by admin
28/08/2026
2

Hướng dẫn tích hợp SDK trong React Native: cấu hình Android, iOS, API key, permission, adapter, Analytics, Crashlytics, Maps, Payment, Auth và checklist release.

Minh họa Firebase Cloud Messaging gửi push notification tới ứng dụng React Native trên Android và iOS

Hướng dẫn tích hợp Firebase Cloud Messaging (FCM) vào React Native từ A-Z

by admin
02/08/2026
0

Hướng dẫn tích hợp Firebase Cloud Messaging vào React Native từ A-Z: Android, iOS/APNs, quyền notification, FCM token, foreground, background và backend.

Minh họa các hook nâng cao trong React Native kết nối với ứng dụng mobile

Các hook nâng cao trong React Native: dùng đúng để code gọn và tối ưu hiệu năng

by admin
30/07/2026
0

Hướng dẫn chi tiết các hook nâng cao trong React Native: useReducer, useContext, useMemo, useCallback, useRef, transition, custom hook và tối ưu hiệu năng.

0 0 votes
Article Rating
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
AE Dev

AE Dev mang đến các bài viết về lập trình, mobile app, backend, frontend, WordPress và công nghệ, phù hợp cho developer muốn học hỏi và cập nhật kiến thức thực tế.

Recent Posts

  • React Native: tránh bàn phím che form với KeyboardAvoidingView và ScrollView
  • Phỏng vấn JavaScript: giải thích event loop, microtask và async/await
  • Deep link mobile an toàn: đúng domain chưa đủ, còn route và quyền đọc

Categories

  • AI
  • Backend
  • Đánh giá
  • DevOps
  • Flutter
  • Hướng dẫn
  • Lập trình Mobile
  • Phỏng vấn
  • React Native
  • Uncategorized

Weekly Newsletter

  • Buy JNews
  • Support Forum
  • Pre-sale Question
  • Contact Us

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

Welcome Back!

Login to your account below

Forgotten Password?

Retrieve your password

Please enter your username or email address to reset your password.

Log In
No Result
View All Result
  • Trang chủ
  • AI
  • Mobile
  • React Native
  • Backend
  • DevOps
  • Hướng dẫn
  • Flutter

© 2026 AE Dev - Blog công nghệ, lập trình và chia sẻ kiến thức IT.

wpDiscuz
0
0
Would love your thoughts, please comment.x
()
x
| Reply