Lebih lanjut ke konten utama

Native Base Picker: Pengaturan, Pengaturan Tampilan & Perbaikan Android

Implementasi Native Base Picker di React Native. Meliputi pengaturan, keadaan, pengaturan tampilan, dan perbaikan kritikal untuk bug onValueChange pada Android. Panduan cepat.

Martin Donadieu

Martin Donadieu

Pengembang Konten

Native Base Picker: Pengaturan, Pengaturan Tampilan & Perbaikan Android

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

Kesalahan itu adalah mengapa NativeBase Picker masih menangkap pengembang berpengalaman dengan tidak sengaja. Pengaturan sederhana, pengaturan tampilan dapat diatur, tetapi keandalan produksi bergantung pada memahami satu gagal Android yang spesifik yang sebagian besar panduan mengabaikan atau tidak pernah menyebutkannya.

Tabel Konten

Membuat Mulai dengan NativeBase Picker

Pilih biasanya merupakan salah satu komponen yang ditambahkan terlambat dalam sprint. Pilih negara, bidang status, jenis janji, pilihan pengiriman. Ini terasa kecil sampai perilaku platform mulai bocor ke UI.

Berita baiknya adalah bahwa NativeBase Picker Mudah untuk menampilkan di layar. Ini dibangun untuk menampilkan pilih asli pada iOS dan Android dan menggantikan pilih React Native yang sudah usang di setup NativeBase yang lebih lama, sehingga banyak kode lama masih bergantung padanya.

Tampilan workspace pengembang yang menampilkan 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 pilih yang paling sederhana yang mungkin.

If 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. Pemilih 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 pemilih pertama tanpa abstraksi tambahan

Pertama kali ini harus menjawab hanya dua pertanyaan:

  • Apakah itu terrender dengan benar: Anda ingin memastikan bahwa field muncul di dalam layout, menghormati jarak, dan membuka di kedua platform.
  • Apakah jalur import Anda benar: Projek NativeBase sering gagal karena alasan yang sederhana seperti menggabungkan API komponen lama dan baru.
  • Apakah nilai yang dipilih dikontrol: Meskipun prototipe sementara, gunakan selectedValue dari state. Pilih unggul code menjadi lebih sulit untuk di-debug kemudian.

Aturan praktis: Jangan mulai dengan memetakan data server, aturan tempat, hook analitis, dan validasi ke dalam pilih yang sama. Pertama-tama buat komponen tersebut terlihat dan dikontrol.

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

Mengikat State dan Mengelola Seleksi

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

Jalan standar adalah sederhana. Anda menyimpan nilai saat ini dengan useState, memasukkannya ke dalam selectedValue, dan memperbarui state tersebut di dalam onValueChange. Hal ini sama dengan mindset yang Anda gunakan untuk bidang formulir lain seperti Polanya React Native TextInput, meskipun kontrol UI yang berbeda.

Gunakan nilai yang dikontrol dari awal

Berikut adalah versi yang lebih 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>
    </>
  );
}

Itu code memberikan Anda sumber kebenaran yang dapat diprediksi. UI menggambarkan role, dan setiap fungsi downstream membaca dari keadaan yang sama.

Tetapkan logika pemilihan kecil dan dapat diuji

Masalah biasanya muncul ketika pengembang memuat terlalu banyak onValueChange. Mereka mengambil data, mengubah beberapa potongan keadaan, memicu navigasi, dan merekam analitik dalam 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:

  1. Membuat picker bertanggung jawab hanya untuk memperbarui keadaan pemilihan.
  2. Menggerakkan perilaku aplikasi ke useEffect, di mana Anda dapat menguji dan berpikir tentangnya secara independen.

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

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

Pengaturan Masalah Android pada Bug onValueChange

Ini adalah bagian yang paling banyak 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 kesenjangan lintas platform yang nyata. Pada Android, tidak ada fungsi yang diaktifkan secara kustom yang terikat dengan onValueChange, sementara iOS melakukan, dan kegagalan itu digambarkan sebagai 100% perbedaan fungsi pada Android dengan tingkat kesuksesan 0% untuk fungsi yang diaktifkan pada perangkat Android meskipun implementasi code yang sama. Dokumentasi yang sama menunjuk pengembang ke arah kerja sama atau migrasi, dan mencatat bahwa komponen NativeBase 3.0 Select mencapai 98% tingkat kesuksesan fungsi pengaktifan di kedua platform dalam lingkungan pengujian Ini bandingannya, seperti yang dijelaskan dalam dokumentasi NativeBase picker dan konteks migrasi. Infografis yang menjelaskan bug umum pada komponen NativeBase Picker di Android dan solusinya..

Apa yang sebenarnya rusak di Android

Alasan praktisnya adalah detail implementasi. Di Android, NativeBase Picker bergantung pada spinner native, dan lapisan tersebut tidak menyebarluaskan pendengar acara ke wrapper seperti yang banyak pengembang harapkan. Di iOS, perilaku modal yang terkait dengan sistem acara secara benar.

Bug ini terasa menipu karena Anda melihat UI. Anda bisa membuka pilihan. Anda bahkan bisa memilih item yang terlihat. Tapi fungsi bisnis Anda tidak pernah berjalan.

Polanya gagal biasanya seperti ini:

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

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

Solusi sementara yang dapat bertahan di produksi

Solusi yang paling dapat diandalkan adalah arsitektur, bukan kosmetik. Tetapkan interaksi picker pada menyimpan nilai yang dipilih, lalu bereaksi terhadap perubahan status di luar handler picker.

Mengapa ini membantu:

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

Status tetap sentral:

  • Keterangan: Logika komponen Anda memantau status, bukan saja payload acara picker sendiri.
  • Dampak sampingan menjadi eksplisit: API panggilan, pembaruan bidang terkait, dan pengawasan tidak lagi hidup di dalam callback UI yang rapuh.
  • code lebih mudah diganti nanti: Jika Anda bermigrasi ke 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 Capacitor aplikasi.

Ketika bermigrasi ke Select adalah keputusan yang lebih bersih

Jika picker berada di dalam alur kerja kritis seperti checkout, onboarding, atau penginputan data yang diatur, memperbaiki sekitar perilaku lama mungkin tidak layak. Pada titik itu, berpindah 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 dengan aman.

Jika Anda mempertahankan picker lama, lihatlah sebagai shell UI dengan tanggung jawab minimal. Mindset ini mencegah banyak regresi Android yang diam.

Styling dan Theming Komponen Picker Anda

Pilih 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 gaya kontainer sekitar picker daripada bertarung dengan kontrol native secara langsung.

Gambar tangan memegang smartphone menampilkan aplikasi pemesanan perjalanan dengan menu dropdown picker native base.

Gayai kontainer sebelum menggaya picker

Picker itu sendiri sebagian terikat oleh rendering native. Kontainer memberikan Anda kontrol yang lebih jauh 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 mengalami kelebihan insinyur tema.

Gunakan presentasi yang sadar platform

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

Penyesuaian yang berguna termasuk:

  • Pada iOS: Berikan ruang lapang bagi bidang dan perhatikan bagaimana presentasi modal terkait dengan label sekitar.
  • Pada Android: Periksa potongan teks dan ketinggian spinner default pada beberapa perangkat.
  • Untuk kedua-duanya: Tetapkan teks tempatkan secara visual berbeda dari pilihan nyata.

Perbandingan singkat membantu:

Kesadaran iOS Android
Sikap terbuka Rasa modal Rasa spinner
Harapan ikon Sering lebih dekoratif Sering lebih fungsional
Masalah jarak Tata letak tempat penempatan dapat terasa longgar Teks dapat terasa sempit

Jika antarmuka UI Anda termasuk gradasi, kartu yang berlapis, atau permukaan kontras tinggi, alihkan pembungkus pemilih dengan penanganan yang sama yang Anda gunakan di tempat lain di antarmuka, seperti pola yang digunakan dalam Kerja UI linear React Native.

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

Itulah mengapa radius batas, jarak label, dan warna tempat penempatan lebih penting daripada pemilih kustomisasi eksotis.

Skenario Lanjutan dan Praktik Terbaik

Masalah biasanya muncul setelah komponen keluar dari fase prototipe. Masalah dimulai ketika pilihan datang dari server, aturan validasi berbeda antara platform, dan tempat penempatan tidak bisa berperilaku seperti nilai yang valid.

Kasus sampingan yang sering muncul sangat mengganggu pada iOS. Pengembang sering perlu memuat nilai pilihan dari server sambil mencegah entri tempat penempatan dari dipilih, namun bahan resmi sering tidak menangani jalur tersebut secara langsung. Diskusi komunitas menyoroti bahwa nilai tempat penempatan dapat tetap dipilih pada iOS, yang menyebabkan perilaku tidak konsisten dalam aplikasi nyata, seperti yang dicatat dalam diskusi komunitas React Native tentang nilai pilihan server dan seleksi tempat penempatan 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 secara langsung. Simpan lapisan transformasi kecil antara respons __CAPGO_KEEP_0__ dan komponen.

Langkah format tersebut memberikan kontrak stabil. Picker Anda tidak perlu tahu bentuk internal API.

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

That formatting step gives you a stable contract. Your picker doesn’t need to know the API’s internal shape.

Aturan yang paling aman adalah sederhana. Jangan anggap tempat penempatan sebagai pilihan yang nyata, bahkan jika perpustakaan UI membuatnya mudah untuk menampilkan satu.

Polosan praktis:

Langkah format tersebut memberikan kontrak stabil. Picker Anda tidak perlu tahu bentuk internal __CAPGO_KEEP_0__.

  • Pakai nilai sentinel kosong: Tahan nilai tempat tandingan sebagai '' atau nilai aplikasi lain yang tidak valid.
  • Validasi sebelum mengirim: Tolak nilai kosong dalam validasi formulir, bukan hanya di UI.
  • Matikan aksi hilir: Tidak aktifkan tombol kirim sampai nilai non-tempat tandingan ada.

Untuk aliran yang lebih ketat, tampilkan teks bantuan ketika nilai tempat tandingan tetap dipilih:

const isValidSelection = selectedCategory !== '';

Lalu tutup aksi tombol atau API panggilan Anda dari kondisi tersebut daripada mengandalkan presentasi picker.

Kebiasaan 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: Pastikan bidang ini dapat dipahami oleh pembaca layar.
  • Tetapkan label eksplisit: “Negara” lebih baik daripada “Pilih”.
  • Tes pemulihan keadaan: Buka kembali formulir dan pastikan item yang sebelumnya dipilih masih muncul dengan benar.
  • Tulislah tes unit di sekitar logika yang dikendalikan oleh pilihan: Logika di luar UI paling penting, dan menguji perilaku React membantu Anda melindungi transisi keadaan.

Perubahan keadaan di balik picker biasanya tidak kritis secara bisnis.

Pikiran yang menjaga formulir dinamis stabil adalah pikiran ini. Tatalah NativeBase Picker sebagai permukaan input. Letakkan aturan yang sebenarnya di dalam keadaan, validasi, dan aliran pengiriman.

Kesimpulan

Pilih NativeBase masih berguna ketika Anda memahami di mana pilihan itu gagal. Pengaturan adalah sederhana, gaya adalah kerja, dan daftar pilihan yang dikendalikan oleh server adalah dapat diatasi. Jangan lupa bahwa perangkat lunak Android menghadapi penanganan event yang kritis. Jika Anda mempertahankan logika bisnis di luar callback pilihan yang rapuh dan memindahkannya ke efek yang dikendalikan oleh keadaan, komponen menjadi lebih dapat diprediksi.

Untuk kode lama, solusi tersebut seringnya cukup. Untuk aliran kritis, migrasi ke Select biasanya merupakan investasi yang lebih baik. Dengan cara apapun, kunci adalah sama. Jangan percaya pilih hanya karena itu menampilkan.


Jika tim Anda mengirimkan aplikasi Capacitor atau Electron dan ingin mempercepat JavaScript, CSS, salinan, konfigurasi, dan perbaikan asset tanpa menunggu tinjauan toko, Capgo patut dipertimbangkan. Ini memberikan Anda pembaruan hidup yang ditandatangani, kontrol peluncuran, perlindungan rollback, dan visibilitas rilis sehingga Anda dapat pulih lebih cepat ketika bug UI seperti regresi pilihan melarikan diri ke produksi.

Update langsung untuk aplikasi Capacitor

Ketika bug layer web masih aktif, kirimkan perbaikan melalui Capgo bukan menunggu hari-hari untuk persetujuan toko aplikasi. Pengguna mendapatkan update di latar belakang sementara perubahan native tetap dalam jalur review normal.

Mulai Sekarang

Terbaru dari Blog Kami

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