Anda mungkin telah menghadapi dinding yang sama seperti banyak tim React Native menghadapi dengan Pemilih Basis Nadi Asli. Pemilih dropdown terrender, terlihat baik, iOS berperilaku, dan kemudian Android mengabaikan logika Anda. Tidak ada crash. Tidak ada peringatan. Hanya sebuah pemilih yang tampaknya berfungsi sementara logika bisnis Anda tidak pernah berjalan. onValueChange Native Base Picker: Setup, Styling & Android Fix
Kenapa NativeBase Picker masih mengejutkan pengembang berpengalaman. Pengaturan sederhana, gaya yang dapat diatur, tapi keandalan produksi bergantung pada pemahaman satu kegagalan Android yang sebagian besar panduan mengabaikan atau tidak menyebutkan.
Daftar Isi
- Mulai Menggunakan NativeBase Picker
- Memasang Nilai dan Mengatasi Pilihan
- Mengatasi Bug Android onValueChange
- Styling dan Tema Komponen Pilih Anda
- Skenario Lanjutan dan Praktik Terbaik
- Kesimpulan
Mulai Belajar dengan Picker NativeBase
Pilih biasanya merupakan salah satu komponen yang ditambahkan terlambat dalam sprint. Pemilih negara, bidang status, jenis janji, pilihan pengiriman. Ini terasa kecil sampai perilaku platform mulai bocor ke UI Anda.
Berita baiknya adalah bahwa Pilih NativeBase mudah untuk mendapatkan di layar. Ini dibangun untuk menampilkan picker native di iOS dan Android dan untuk menggantikan picker React Native yang sudah deprecated di setup NativeBase yang lebih lama, sehingga banyak kode lama masih bergantung pada itu.

Pasang komponen di setup React Native normal
Jika proyek Anda sudah menggunakan NativeBase, tugas utama adalah mengimport primitif yang tepat dan menghindari logika wrapper yang tidak perlu pada hari pertama. Mulai dengan picker yang paling sederhana yang mungkin.
Jika Anda bekerja di atas stack mobile dan hybrid, juga membantu untuk memahami bagaimana React code dipaketkan di lingkungan yang lebih luas seperti Alur kerja aplikasi mobile React dengan Capacitor. Picker code tetap familiar, tapi harapan penggunaan berubah.
Contoh dasar seperti ini:
import React, { useState } from 'react';
import { Container, Content, Form, Item, Picker, Icon } from 'native-base';
export default function BasicPickerScreen() {
const [selectedValue, setSelectedValue] = useState('key0');
return (
<Container>
<Content padder>
<Form>
<Item picker>
<Picker
mode="dropdown"
iosIcon={<Icon name="arrow-down" />}
selectedValue={selectedValue}
onValueChange={(value) => setSelectedValue(value)}
>
<Picker.Item label="Choose one" value="key0" />
<Picker.Item label="JavaScript" value="js" />
<Picker.Item label="TypeScript" value="ts" />
<Picker.Item label="React Native" value="rn" />
</Picker>
</Item>
</Form>
</Content>
</Container>
);
}
Tampilkan picker pertama tanpa abstraksi tambahan
Langkah pertama ini harus menjawab hanya dua pertanyaan:
- Apakah itu menampilkan dengan benar: Kamu ingin memastikan bahwa field muncul di dalam layout, menghormati jarak, dan membuka di kedua platform.
- Apakah jalur import Anda sudah benar: Proyek NativeBase sering gagal karena alasan yang sederhana seperti menggabungkan API komponen lama dan baru.
- Apakah nilai yang dipilih dikontrol: Meskipun dalam prototipe sementara, gunakan
selectedValuefrom state. Pemilih tidak terkendali code menjadi lebih sulit untuk di-debug nanti.
Aturan praktis: Tidak mulai dengan menerjemahkan data server, aturan tempat, hook analitis, dan validasi ke dalam pemilih yang sama. Buat komponen terlihat dan dikontrol terlebih dahulu.
Dasar yang disederhanakan itu penting. Ketika Android mulai berperilaku tidak seperti yang diharapkan nanti, Anda akan tahu bahwa masalah bukanlah arsitektur formulir Anda secara keseluruhan. Itu adalah pemilih.
Mengikat Negara dan Mengelola Seleksi
Saat pemilih sudah muncul, tugas berikutnya adalah membuatnya berguna. Di React Native, itu berarti menanganinya seperti input yang dikontrol dan menjaga nilai yang dipilih dalam negara komponen.
Jalan standar adalah sederhana. Anda menyimpan nilai saat ini dengan useStatemengirimkannya ke selectedValuedan memperbarui status di dalamnya onValueChangeContoh ini sama seperti pola lainnya untuk bidang formulir seperti Polanya React Native TextInputmeskipun kontrol UI berbeda
Pilih nilai yang dikontrol dari awal
Contoh versi yang bersih yang saya gunakan sebelum menambahkan validasi atau efek sampingan:
import React, { useState } from 'react';
import { Text } from 'react-native';
import { Form, Item, Picker } from 'native-base';
export default function RolePicker() {
const [role, setRole] = useState('');
return (
<>
<Form>
<Item picker>
<Picker
mode="dropdown"
selectedValue={role}
onValueChange={(value) => setRole(value)}
>
<Picker.Item label="Select a role" value="" />
<Picker.Item label="Admin" value="admin" />
<Picker.Item label="Editor" value="editor" />
<Picker.Item label="Viewer" value="viewer" />
</Picker>
</Item>
</Form>
<Text>Selected role: {role || 'none'}</Text>
</>
);
}
code ini memberikan sumber kebenaran yang dapat diprediksi. UI menggambarkan roledan setiap fungsi downstream membaca dari status yang sama.
Tetapkan logika pemilihan kecil dan dapat diuji
Masalah biasanya muncul ketika pengembang memuat onValueChangeMereka mengambil data, mengubah beberapa potongan status, memicu navigasi, dan mengirimkan analitik di satu fungsi inline. Ketika perilaku picker gagal, debugging menjadi menyakitkan.
Polanya yang lebih baik adalah memisahkan penyimpanan nilai dari efek sampingan:
import React, { useEffect, useState } from 'react';
import { Text } from 'react-native';
import { Form, Item, Picker } from 'native-base';
export default function DepartmentPicker() {
const [department, setDepartment] = useState('');
const [message, setMessage] = useState('No department selected');
useEffect(() => {
if (!department) {
setMessage('No department selected');
return;
}
setMessage(`Department selected: ${department}`);
}, [department]);
return (
<>
<Form>
<Item picker>
<Picker
selectedValue={department}
onValueChange={setDepartment}
>
<Picker.Item label="Select department" value="" />
<Picker.Item label="Sales" value="sales" />
<Picker.Item label="Support" value="support" />
<Picker.Item label="Operations" value="operations" />
</Picker>
</Item>
</Form>
<Text>{message}</Text>
</>
);
}
Struktur ini melakukan dua hal yang berguna:
- Itu membuat picker bertanggung jawab hanya untuk memperbarui status pilihan.
- It pindahkan perilaku aplikasi ke
useEffectdi mana Anda dapat menguji dan berpikir secara independen.
Jika komponen formulir tidak dapat secara andal memberitahu aplikasi Anda apa nilai yang dipilih, maka setiap efek sampingan yang terikat dengan itu menjadi curiga.
Poin itu menjadi kritis pada Android, di mana aliran acara NativeBase Picker tidak selalu berlaku.
Penyelidikan Bug Android onValueChange
Bagian ini yang paling artikel lewatkan. NativeBase Picker dapat terlihat sehat pada Android sementara gagal pada saat yang tepat Anda membutuhkannya untuk melakukan pekerjaan.
Dokumentasi komunitas seputar implementasi picker yang lebih tua menjelaskan pemisahan yang sebenarnya di antara platform. Android tidak memicu fungsi-fungsi kustom yang terikat dengan onValueChangesementara iOS melakukannyadan gagal itu dijelaskan sebagai 100% disparitas fungsi yang berfungsi pada Android dengan tingkat kesuksesan 0% untuk mengaktifkan fungsi pada perangkat Android meskipun implementasi code yang sama di dalam laporan-laporan yang terdokumentasi. Dokumentasi yang sama menunjukkan arah kerja sama bagi para pengembang untuk mengatasi masalah atau melakukan migrasi, dan mencatat bahwa komponen NativeBase 3.0 Select mencapai 98% tingkat kesuksesan fungsi pengaktifan di kedua platform dalam lingkungan pengujian bandingkan dengan yang dijelaskan dalam dokumentasi dan konteks migrasi NativeBase picker Infografis yang menjelaskan bug umum pada komponen NativeBase Picker pada Android dan solusinya.

Alasan praktisnya adalah detail implementasi. Pada Android, NativeBase Picker bergantung pada spinner native, dan lapisan tersebut tidak mempropagasi penggunaan event ke wrapper seperti yang banyak pengembang harapkan. Pada iOS, perilaku modal yang terkait dengan sistem event secara benar.
Itu mengapa bug ini terasa menipu. Anda melihat UI. Anda bisa membuka pilihan. Anda bahkan bisa memilih item yang terlihat. Tapi fungsi bisnis Anda tidak pernah berjalan.
Polanya yang gagal biasanya terlihat seperti ini:
Pada iOS, ini mungkin berfungsi seperti yang diharapkan. Pada Android, picker dapat menampilkan sementara fungsi-fungsi tersebut tidak pernah aktif.
<Picker
selectedValue={status}
onValueChange={(value) => {
setStatus(value);
saveStatusToApi(value);
trackSelection(value);
updateDependentFields(value);
}}
>
Pada iOS, ini mungkin berfungsi seperti yang diharapkan. Pada Android, picker dapat menampilkan sementara fungsi-fungsi tersebut tidak pernah aktif.
Aplikasi pengganti yang dapat bertahan di produksi
Pengganti yang paling dapat diandalkan adalah arsitektural, bukan kosmetik. Tetapkan interaksi picker pada penyimpanan nilai yang dipilih, kemudian reaksi terhadap perubahan status di luar handler picker.
import React, { useEffect, useState } from 'react';
import { Form, Item, Picker } from 'native-base';
export default function StatusPicker() {
const [status, setStatus] = useState('');
const [didMount, setDidMount] = useState(false);
useEffect(() => {
if (!didMount) {
setDidMount(true);
return;
}
if (!status) return;
runStatusSideEffects(status);
}, [status, didMount]);
const runStatusSideEffects = (value) => {
console.log('Selected status:', value);
// call validation, API sync, or dependent form updates here
};
return (
<Form>
<Item picker>
<Picker
selectedValue={status}
onValueChange={setStatus}
>
<Picker.Item label="Select status" value="" />
<Picker.Item label="Pending" value="pending" />
<Picker.Item label="Approved" value="approved" />
<Picker.Item label="Rejected" value="rejected" />
</Picker>
</Item>
</Form>
);
}
Mengapa ini membantu:
- Status tetap sentral: Logika komponen Anda mengawasi
status, bukan payload event picker sendiri. - Dampak samping menjadi eksplisit: API panggilan, pembaruan field yang tergantung, dan tracking tidak lagi hidup di dalam callback UI yang rapuh.
- Pengganti code lebih mudah diganti nanti: Jika Anda beralih dari NativeBase Picker, logika bisnis sebagian besar tetap utuh.
Untuk proyek Android-heavy, saya juga merekomendasikan melakukan pengujian pada perangkat nyata awal, terutama jika aplikasi Anda sudah memiliki kompleksitas pengemasan native seperti Pengaturan Android untuk aplikasi Capacitor.
Ketika migrasi ke Select adalah keputusan yang lebih bersih
Jika picker berada di dalam alur kerja yang kritis seperti checkout, onboarding, atau penginputan data yang terregulasi, memperbaiki sekitar perilaku lama mungkin tidak sepadan. Pada titik itu, memindahkan ke NativeBase 3.0 Select biasanya adalah keputusan jangka panjang yang lebih aman.
Bug bukan hanya mengganggu. Ini mengubah tempat di mana Anda bisa menempatkan logika bisnis.
Jika Anda mempertahankan picker lama, lihatlah sebagai shell UI dengan tanggung jawab minimal. Mindset ini mencegah banyak regresi Android yang diam.
Mengatur Tampilan dan Tema Komponen Picker Anda
Picker yang berfungsi masih terlihat tidak selesai jika tidak sesuai dengan tampilan aplikasi lainnya. NativeBase memberikan Anda cukup hook untuk membuat kontrol terasa sengaja, tetapi hasil yang paling bersih biasanya datang dari mengatur kontainer sebelum mengatur picker.

Alihkan gaya wrapper sebelum mengatur gaya picker
Picker itu sendiri sebagian terikat oleh rendering native. Wrapper memberikan Anda kontrol yang lebih besar atas jarak, penanganan batas, dan ritme tata letak.
Polanya yang praktis:
import React, { useState } from 'react';
import { StyleSheet } from 'react-native';
import { Form, Item, Picker, Icon } from 'native-base';
export default function StyledPicker() {
const [country, setCountry] = useState('');
return (
<Form>
<Item style={styles.pickerWrapper} picker>
<Picker
mode="dropdown"
iosIcon={<Icon name="arrow-down" style={styles.icon} />}
textStyle={styles.pickerText}
selectedValue={country}
onValueChange={setCountry}
>
<Picker.Item label="Select country" value="" />
<Picker.Item label="Germany" value="de" />
<Picker.Item label="Japan" value="jp" />
<Picker.Item label="Brazil" value="br" />
</Picker>
</Item>
</Form>
);
}
const styles = StyleSheet.create({
pickerWrapper: {
borderWidth: 1,
borderColor: '#D1D5DB',
borderRadius: 10,
marginTop: 12,
paddingLeft: 8,
backgroundColor: '#FFFFFF',
},
pickerText: {
color: '#111827',
fontSize: 16,
},
icon: {
color: '#111827',
fontSize: 18,
},
});
Langkah itu biasanya mendapatkan Anda sebagian besar jalan tanpa mengover-engineer penggantian tema.
Pilih presentasi yang sadar platform
Penggunaan iOS dan Android jarang memerlukan gaya yang sama. Mereka memerlukan niat yang konsisten. Token visual yang sama masih dapat memerlukan padding yang berbeda, penempatan ikon, atau mode pemilih.
Penyesuaian berguna termasuk:
- Pada iOS: Berikan ruang bagi bidang dan perhatikan bagaimana presentasi modal terkait dengan label sekitar.
- Pada Android: Periksa clipping teks dan ketinggian spinner default pada beberapa perangkat.
- Untuk kedua-duanya: Tetapkan teks tempat yang terlihat berbeda dari pilihan nyata.
Perbandingan singkat membantu:
| Kesalahan | iOS | Android |
|---|---|---|
| Penampilan terbuka | Rasa Modal | Rasa Spinner |
| Harapan Icon | Seringkali lebih dekoratif | Seringkali lebih fungsional |
| Issue Spasi | Tata letak tempat pengganti dapat terasa longgar | Teks dapat terasa sempit |
Jika antarmuka UI Anda termasuk gradient, kartu berlapis, atau permukaan kontras tinggi, alihkan pengemas pilih dengan penanganan yang sama yang Anda gunakan di tempat lain di antarmuka, seperti pola-pola yang digunakan dalam pekerjaan gradient linear React Native Pekerjaan linear React Native.
Catatan Desain: Pengguna menilai picker kurang dari dropdown itu sendiri dan lebih dari bagaimana bidang tertutup berada di dalam formulir.
Alasannya, radius border, jarak label, dan warna placeholder lebih penting daripada customisasi picker yang eksotis.
Skenario Lanjutan dan Praktik Terbaik
Banyak bug picker muncul setelah komponen meninggalkan fase prototipe. Masalah dimulai ketika pilihan datang dari server, aturan validasi berbeda antara platform, dan placeholder tidak dapat berperilaku seperti nilai yang valid.
Salah satu kasus sampingan yang sering muncul sangat mengganggu di iOS. Pengembang sering perlu memuat nilai picker dari server sambil mencegah entry placeholder dari dapat dipilih, namun bahan resmi sering tidak menangani jalur tersebut secara langsung. Diskusi komunitas menyoroti bahwanilai placeholder dapat tetap dapat dipilih di iOS yang menyebabkan perilaku tidak konsisten di aplikasi nyata, seperti yang dicatat dalam diskusi komunitas React Native tentang nilai picker yang dimuat dari server dan seleksi placeholder.

Muat nilai picker dari data server dengan aman
Salah satu kesalahan yang paling sering saya lihat adalah menganggap data yang diambil sebagai siap digunakan langsung oleh picker. Simpan lapisan transformasi kecil antara respons API dan komponen.
import React, { useEffect, useState } from 'react';
import { Form, Item, Picker } from 'native-base';
export default function DynamicCategoryPicker() {
const [categories, setCategories] = useState([]);
const [selectedCategory, setSelectedCategory] = useState('');
useEffect(() => {
const loadCategories = async () => {
const response = await fetch('https://example.com/api/categories');
const data = await response.json();
const formatted = data.map((item) => ({
label: item.name,
value: String(item.id),
}));
setCategories(formatted);
};
loadCategories();
}, []);
return (
<Form>
<Item picker>
<Picker
selectedValue={selectedCategory}
onValueChange={setSelectedCategory}
>
<Picker.Item label="Select category" value="" />
{categories.map((item) => (
<Picker.Item
key={item.value}
label={item.label}
value={item.value}
/>
))}
</Picker>
</Item>
</Form>
);
}
Langkah formatasi itu memberikan kontrak yang stabil. Pilihannya tidak perlu mengetahui bentuk internal API.
Mencegah seleksi tempat pengganti pada iOS
Aturan yang paling aman adalah sederhana. Jangan anggap tempat pengganti sebagai pilihan yang sebenarnya, bahkan jika perpustakaan UI membuatnya mudah untuk menampilkan satu.
Polanya yang praktis:
- Pilih nilai pengganti kosong: Tetapkan nilai pengganti sebagai
''atau nilai aplikasi yang tidak valid lainnya. - Validasi sebelum mengirim: Mengacu nilai kosong dalam validasi formulir, bukan hanya di UI.
- Mengaktifkan aksi hilir: Jangan mengaktifkan tombol submit sampai nilai non-pengganti ada.
Untuk aliran yang lebih ketat, tampilkan teks bantuan ketika tempat pengganti tetap dipilih:
const isValidSelection = selectedCategory !== '';
Kemudian tutup tombol aksi Anda atau API panggilan dari kondisi tersebut daripada mengandalkan presentasi picker.
Keamanan aksesibilitas dan kebiasaan produksi
Pilih-pilih seringkali lolos dari tinjauan aksesibilitas karena terlihat asli. Mereka masih memerlukan label yang jelas dan keadaan yang dapat diprediksi.
Beberapa kebiasaan membayar cepat:
- Tambahkan label aksesibilitas: Jadikan bidang tersebut dapat dipahami oleh pembaca layar.
- Tetapkan label yang eksplisit: “Negara” lebih baik daripada “Pilih”.
- Uji keadaan restorasi: Buka kembali formulir dan pastikan item yang dipilih sebelumnya masih muncul dengan benar.
- Tulis uji unit di sekitar logika yang dipicu oleh pemilihan: Logika di luar UI paling penting, dan menguji unit perilaku React membantu Anda melindungi transisi keadaan.
A pilihan jarang kritis secara bisnis sendiri. Perubahan keadaan di baliknya biasanya adalah.
Itu adalah mindset yang menjaga formulir dinamis stabil. Tatalah Pemilih NativeBase sebagai permukaan input. Masukkan aturan yang sebenarnya ke dalam aliran keadaan, validasi, dan pengiriman.
Kesimpulan
Pemilih NativeBase masih berguna ketika Anda memahami di mana ia rusak. Pengaturan adalah sederhana, gaya adalah kerja, dan daftar pilihan yang dikendalikan server adalah dapat diatur. Jaringan kritikal adalah pengelolaan event Android. Jika Anda menjaga logika bisnis di luar panggilan callback pemilih yang rapuh dan memindahkannya ke dalam efek yang dikendalikan keadaan, komponen menjadi lebih dapat diprediksi.
Untuk kodebase yang lebih tua, itu adalah kerja sama yang cukup. Untuk aliran yang kritis, migrasi ke Select biasanya adalah investasi yang lebih baik. Dengan cara apa pun, kunci adalah sama. Jangan percaya pemilih hanya karena ia menampilkan.
Jika tim Anda mengirimkan aplikasi Capacitor atau Electron dan ingin mempercepat JavaScript, CSS, salinan, konfigurasi, dan perbaikan aset tanpa menunggu ulasan toko Capgo adalah patut dilihat. Ia memberikan Anda pembaruan hidup yang ditandatangani, kontrol peluncuran, perlindungan rollback, dan visibilitas rilis sehingga Anda dapat pulih lebih cepat ketika bug UI seperti regresi pemilih melarikan diri ke produksi.