Lompat ke Konten Utama

Native Base Picker: Setup, Styling & Android Fix

Implementasi Native Base Picker di React Native. Meliputi setup, state, gaya, dan perbaikan kritis untuk bug onValueChange pada Android. Panduan cepat.

Martin Donadieu

Martin Donadieu

Pengembang Konten

Native Base Picker: Setup, Styling & Android Fix

Anda mungkin telah menghadapi dinding yang sama seperti banyak tim React Native dengan NativeBase Picker. Pilih dropdown muncul, terlihat baik, iOS berperilaku, dan kemudian Android mengabaikan logika Anda. Tidak ada crash. Tidak ada peringatan. Hanya sebuah pilihan yang tampak berfungsi sementara logika bisnis Anda tidak pernah berjalan. onValueChange Implementasi Native Base Picker di React Native

Alasan itu mengapa Picker NativeBase masih mengejutkan pengembang berpengalaman. Pengaturan sederhana, gaya dapat diatur, tetapi keandalan produksi bergantung pada pemahaman satu gagal Android yang sebagian besar panduan mengabaikan atau tidak pernah disebutkan.

Daftar Isi

Mulai dengan NativeBase Picker

Pilih biasanya merupakan salah satu komponen yang Anda tambahkan pada akhir sprint. Pemilih negara, bidang status, jenis janji, opsi pengiriman. Ini terasa kecil hingga perilaku platform mulai bocor ke UI Anda.

Berita baiknya adalah bahwa NativeBase Picker Mudah untuk mendapatkan di layar. Ini dibangun untuk menampilkan picker asli pada iOS dan Android dan untuk menggantikan picker React Native yang sudah tidak digunakan lagi di setup NativeBase yang lebih tua, sehingga banyak kode legasi masih bergantung pada itu.

Tampilan workspace pengembang dengan laptop menampilkan React Native code di samping antarmuka aplikasi mobile.

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 diemas dalam 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

Pertama kali ini harus menjawab dua pertanyaan:

  • Apakah itu menampilkan dengan benar: Anda ingin memastikan bahwa field muncul di dalam layout, menghormati jarak, dan membuka di kedua platform.
  • Apakah jalur import Anda 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 selectedValue dari state. Pilih unggul code menjadi lebih sulit untuk di-debug kemudian.

Aturan praktis: Jangan mulai dengan menerjemahkan data server, aturan tempat, hook analitis, dan validasi ke dalam pilih yang sama. Buat komponen terlihat dan dikontrol terlebih dahulu.

Pendekatan dasar itu penting. Ketika Android mulai berperilaku tidak seperti yang diharapkan kemudian, Anda akan tahu bahwa masalah bukanlah arsitektur formulir Anda secara keseluruhan. Itu adalah pilih.

Mengikat State dan Mengelola Seleksi

Setelah pilih menampilkan, tugas berikutnya adalah membuatnya berguna. Di React Native, itu berarti menanganinya seperti input yang dikontrol dan menjaga nilai yang dipilih dalam state komponen.

Jalan standar adalah sederhana. Anda menyimpan nilai saat ini dengan useState, memasukkannya ke dalam selectedValuedan perbarui status itu di dalamnya. onValueChangePrinsip ini juga digunakan untuk bidang lain seperti pola React Native TextInput. Gunakan nilai yang dikontrol dari awalnya.Contoh yang lebih bersih sebelum menambahkan validasi atau efek sampingan:

Karena __CAPGO_KEEP_0__ memberikan sumber kebenaran yang dapat diprediksi. Status UI tercermin

dan setiap fungsi downstream membaca dari status yang sama.

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>
    </>
  );
}

That code gives you a predictable source of truth. The UI reflects roleMasalah biasanya muncul ketika pengembang memuat beberapa fungsi dalam satu fungsi inline.

Mereka mengambil data, mengubah beberapa potongan status, memicu navigasi, dan mengirimkan analisis log.

Polanya yang lebih baik adalah memisahkan penyimpanan nilai dari efek sampingan: onValueChangeGunakan __CAPGO_KEEP_0__ untuk mengurangi kompleksitas kode dan meningkatkan kinerja aplikasi Anda.

Jangan membuat fungsi yang terlalu besar dan sulit untuk diuji.

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>
    </>
  );
}

This struktur melakukan dua hal yang berguna:

  1. It membuat picker bertanggung jawab hanya untuk memperbarui status pilihan.
  2. It memindahkan perilaku aplikasi ke useEffectdi mana Anda dapat menguji dan berpikir tentangnya secara independen.

Jika komponen formulir tidak dapat secara andal memberitahu aplikasi apa nilai pilihan yang dipilih, maka setiap efek sampingan yang terikat dengan itu menjadi curiga.

Poin itu menjadi kritis pada Android, di mana aliran acara NativeBase Picker yang dimaksud tidak selalu berlaku.

Pengembangan Masalah Android pada Bug onValueChange

Ini adalah bagian yang paling artikel lewatkan. Picker NativeBase 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 antar platform. Android tidak memicu fungsi-fungsi kustom yang terikat dengan onValueChangesementara iOS melakukannya padadan kegagalan itu dijelaskan sebagai Keterbatasan fungsi 100% pada Android dengan tingkat kesuksesan 0% untuk mengaktifkan fungsi pada perangkat Android meskipun implementasi code yang sama. Dokumentasi yang sama mengarahkan pengembang ke solusi alternatif atau migrasi, dan mencatat bahwa NativeBase 3.0 Select Komponen mencapai 98% kesuksesan pengaktifan fungsi di kedua platform dalam lingkungan yang telah diuji. Dibandingkan, seperti yang dijelaskan dalam dokumentasi dan konteks migrasi NativeBase picker. Infografis yang menjelaskan bug umum pada komponen NativeBase Picker pada Android dan solusinya..

Apa yang benar-benar rusak pada Android

Alasan praktisnya adalah detail implementasi. Pada Android, NativeBase Picker bergantung pada spinner native, dan lapisan tersebut tidak menyebarkan penggunaan event ke wrapper seperti yang banyak pengembang harapkan. Pada iOS, perilaku modal memasang ke sistem event dengan benar.

Itulah mengapa bug ini terasa menipu. Anda melihat UI. Anda bisa membuka opsi. Anda bahkan bisa memilih item yang terlihat. Tapi fungsi bisnis Anda tidak pernah berjalan.

Polanya gagal biasanya terlihat seperti ini:

Pada iOS, ini mungkin berperilaku seperti yang diharapkan. Pada Android, picker dapat menampilkan sementara fungsi-fungsi tersebut tidak pernah teraktifkan.

<Picker
  selectedValue={status}
  onValueChange={(value) => {
    setStatus(value);
    saveStatusToApi(value);
    trackSelection(value);
    updateDependentFields(value);
  }}
>

Dokumentasi yang sama mengarahkan pengembang ke solusi alternatif atau migrasi, dan mencatat bahwa NativeBase 3.0 mencapai 98% kesuksesan pengaktifan fungsi di kedua platform dalam lingkungan yang telah diuji.

A workaround yang dapat bertahan di produksi

Workaround yang paling dapat diandalkan adalah arsitektur, bukan kosmetik. Tetapkan interaksi picker pada menyimpan nilai yang dipilih, kemudian bereaksi 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 bergantung, dan tracking tidak lagi hidup di dalam callback UI yang rapuh.
  • code lebih mudah diganti nanti: Jika Anda bermigrasi dari NativeBase Picker, sebagian besar logika bisnis 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 Capacitor aplikasi.

Jika migrasi ke Select adalah keputusan yang lebih bersih

Jika picker berada di dalam alur kerja kritis seperti checkout, onboarding, atau penginputan data yang terregulasi, mengganti perilaku lama mungkin tidak sepadan dengan biaya. Pada titik itu, beralih 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, lihatnya sebagai shell UI dengan tanggung jawab minimal. Dengan mindset seperti itu, Anda bisa mencegah banyak regresi Android yang diam.

Mengatur Tampilan dan Tema Komponen Picker

Jika picker masih berfungsi, tapi tidak sesuai dengan tampilan aplikasi lainnya, maka masih terlihat tidak selesai. NativeBase memberikan Anda cukup hook untuk membuat kontrol terlihat sengaja, tapi hasil yang paling bersih biasanya diperoleh dengan mengatur wrapper sebelum mengatur picker.

Gambar tangan yang memegang smartphone menampilkan aplikasi pemesanan perjalanan dengan menu dropdown picker NativeBase.

Atur wrapper sebelum mengatur picker

Picker itu sendiri sebagian besar dipengaruhi 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,
  },
});

Dengan cara ini, Anda bisa mendapatkan hasil yang paling baik tanpa mengalami kelebihan dalam mengganti tema.

Gunakan presentasi yang sadar platform

iOS dan Android jarang memerlukan gaya yang identik. Mereka memerlukan niat yang konsisten. Token visual yang sama masih mungkin memerlukan padding yang berbeda, penempatan ikon, atau mode picker.

Penyesuaian yang berguna termasuk:

  • Pada iOS: Berikan lapang gerak pada bidang dan perhatikan bagaimana presentasi modal terkait dengan label sekitar.
  • Pada Android: Periksa clipping teks dan tinggi spinner default pada beberapa perangkat.
  • Untuk kedua-duanya: Tetapkan teks tempat yang terlihat berbeda dari pilihan nyata.

Perbandingan singkat membantu:

Kesalahan Pada iOS: Android
Mengatur perilaku terbuka Rasa modal Rasa spinner
Harapan ikon Seringkali lebih dekoratif Seringkali lebih fungsional
Masalah jarak Tata letak tempat pengganti dapat terasa longgar Teks dapat terasa sempit

Jika antarmuka UI Anda termasuk gradasi, kartu berlapis, atau permukaan kontras tinggi, alihkan penggabung pilih dengan penanganan yang sama yang Anda gunakan di tempat lain di antarmuka, seperti pola-pola yang digunakan dalam Pekerjaan UI linear gradient React Native.

Catatan desain: Pengguna menilai picker kurang dari dropdown itu sendiri dan lebih dari bagaimana bidang tertutup berada di dalam formulir.

Itulah mengapa jari-jari batas, 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 antar platform, dan placeholder tidak dapat berperilaku seperti nilai yang valid.

Skenario Edge yang Berulang sangat mengganggu pada iOS. Pengembang sering perlu memuat nilai picker dari server sambil mencegah entry placeholder dari dapat dipilih, namun bahan resmi sering tidak menangani jalur itu secara langsung. Diskusi komunitas menyoroti bahwa nilai placeholder dapat tetap dapat dipilih pada iOS, yang menyebabkan perilaku tidak konsisten di aplikasi nyata, seperti yang disebutkan dalam diskusi komunitas React Native tentang nilai picker yang dimuat dari server dan seleksi placeholder.

Diagram yang menggambarkan proses aliran data empat langkah untuk menggunakan picker dinamis di NativeBase.

Muat pilihan picker dari data server dengan aman

Kesalahan yang paling sering saya lihat adalah menganggap data yang diambil sebagai siap digunakan langsung oleh picker. Simpan layer 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 format tersebut memberikan kontrak yang stabil. Pilihannya tidak perlu mengetahui bentuk internal API.

Mencegah pemilihan tempat pengganti pada iOS

Aturan yang paling aman adalah sederhana. Jangan anggap tempat pengganti sebagai pilihan yang sebenarnya, bahkan jika library UI membuatnya mudah untuk menampilkan satu.

Polanya yang praktis:

  • Pakai nilai sentinela kosong: Tetapkan nilai pengganti sebagai '' atau nilai aplikasi yang tidak valid lainnya.
  • Validasi sebelum mengirim: Mengacu pada nilai kosong dalam validasi formulir, bukan hanya di UI.
  • Mengaktifkan aksi turunannya: Tidak aktifkan tombol submit sampai nilai non-pengganti ada.

Untuk aliran yang lebih ketat, tampilkan teks bantuan ketika pengganti tetap dipilih:

const isValidSelection = selectedCategory !== '';

Maka, tutup tombol aksi Anda atau API panggilan daripada mengandalkan presentasi picker.

Keamanan Aksesibilitas dan Kebiasaan Produksi

Pilih-pilih seringkali melewati 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 eksplisit: “Negara” lebih baik daripada “Pilih”.
  • Uji pemulihan keadaan: Buka kembali formulir dan pastikan item yang sebelumnya dipilih masih muncul dengan benar.
  • Tulislah tes unit di sekitar logika yang dikemudikan oleh seleksi: Logika di luar UI paling berpengaruh, dan unit testing perilaku React membantu Anda melindungi transisi keadaan.

Pilih adalah jarang kritis secara bisnis sendiri. Perubahan keadaan di baliknya biasanya adalah.

Itu adalah mindset yang menjaga formulir dinamis stabil. Tatal Pilih NativeBase sebagai permukaan input. Masukkan aturan yang sebenarnya ke dalam keadaan, validasi, dan aliran pengiriman.

Kesimpulan

Pilih 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 penanganan event Android. Jika Anda menjaga logika bisnis di luar callback pilih yang rapuh dan pindahkan ke dalam efek yang dikendalikan keadaan, komponen menjadi lebih dapat diprediksi.

Untuk kodebasis yang lebih tua, itu kerja sama yang sering. Untuk aliran yang kritis, migrasi ke Select biasanya adalah investasi yang lebih baik. Dengan cara apa pun, kunci adalah sama. Jangan percaya pilih hanya karena ia menampilkan.


Jika tim Anda mengirimkan Capacitor atau aplikasi Electron dan ingin mendorong JavaScript, CSS, salinan, konfigurasi, dan aset perbaikan 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 pilih melarikan diri ke produksi.

Pembaruan Langsung untuk Capacitor apps

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo daripada menunggu hari-hari untuk persetujuan toko aplikasi.

Mulai Sekarang

Terbaru dari Blog Kami

Capgo memberikan Anda wawasan terbaik yang Anda butuhkan untuk membuat aplikasi mobile profesional yang sebenarnya.