Ke halaman utama
Martin Donadieu

Pengembang Konten onValueChange Pemilih Basis Nadi Asli: Pengaturan, Pengaturan gaya & Perbaikan Android

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

Daftar Isi

Mulai dengan NativeBase Picker

Pilih biasanya merupakan salah satu komponen yang Anda tambahkan terlambat dalam sprint. Pemilih negara, status lapangan, 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 asli pada iOS dan Android dan untuk menggantikan picker React Native yang sudah deprecated di setup NativeBase yang lebih lama, sehingga banyak kode legasi masih bergantung pada itu.

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

Pasang komponen di setup React Native yang 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

Pasang picker pertama ini harus menjawab hanya 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 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 selectedValue from state. Pemilih tidak terkendali code menjadi lebih sulit untuk di-debug kemudian.

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

Dasar yang disederhanakan itu penting. Ketika Android mulai berperilaku tidak seperti yang diharapkan kemudian, Anda akan tahu bahwa masalah bukanlah arsitektur formulir Anda secara keseluruhan. Masalahnya adalah pemilih.

Mengikat Negara dan Mengatasi Pilihan

Setelah pemilih terrender, tugas berikutnya adalah membuatnya berguna. Di React Native, itu berarti menganggapnya seperti input yang dikendalikan 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 pola lainnya adalah Polanya sama seperti pola 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 memberikan Anda sumber kebenaran yang dapat diprediksi. UI menggambarkan roledan setiap fungsi downstream membaca dari status yang sama.

Jaga logika pemilihan kecil dan dapat diuji

Masalah biasanya muncul ketika pengembang memuat onValueChange. Mereka 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:

  1. Membuat picker bertanggung jawab hanya untuk memperbarui status pilihan.
  2. Menggerakkan 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 ini menjadi kritis pada Android, di mana aliran acara NativeBase Picker tidak selalu berlaku.

Mengatasi Bug Android onValueChange

Bagian ini yang paling banyak artikel lewatkan. Picker NativeBase dapat terlihat sehat pada Android, tetapi gagal pada saat yang tepat Anda membutuhkannya untuk melakukan pekerjaan.

Dokumentasi komunitas seputar implementasi picker yang lebih tua menggambarkan pemisahan yang sebenarnya di antara platform. Android tidak memicu fungsi-fungsi kustom yang terikat dengan onValueChangesementara iOS melakukannyadan kegagalan itu digambarkan sebagai 100% disparitas fungsi pada Android dengan tingkat kesuksesan 0% untuk mengaktifkan fungsi pada perangkat Android meskipun implementasi code identik di dalam laporan yang terdokumentasi. Dokumentasi yang sama menunjukkan arah kerja sama pengembang untuk mengatasi atau migrasi, dan mencatat bahwa komponen NativeBase 3.0 Select mencapai 98% kesuksesan fungsi pengaktifan di kedua platform dalam lingkungan yang diuji bandingkan dengan yang dijelaskan dalam konteks migrasi dan dokumentasi NativeBase picker.

Infografis yang menjelaskan bug umum pada komponen NativeBase Picker pada Android dan solusinya

Apa yang sebenarnya mengganggu 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 yang terkait dengan sistem event secara benar.

Itu 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 dijalankan.

Polanya gagal biasanya seperti ini:

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

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

Aplikasi kerja yang dapat bertahan di produksi

Solusi yang paling dapat diandalkan adalah arsitektur, bukan kosmetik. Tetapkan interaksi picker pada penyimpanan 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 hal ini membantu:

  • Status tetap sentral: Logika komponen Anda mengawasi status, bukan payload event picker sendiri.
  • Efek sampingan 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, 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.

When 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. Pada titik itu, beralih ke NativeBase 3.0 Select biasanya adalah keputusan yang lebih aman dalam jangka panjang.

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 ini, Anda bisa mencegah banyak regresi Android yang diam.

Mengatur Tampilan dan Tema Komponen Picker

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 picker.

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

Style wrapper sebelum mengatur 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,
  },
});

Metode ini biasanya mendapatkan Anda sebagian besar jalan tanpa mengover-engineer penggantian tema.

Penggunaan presentasi yang sadar platform

Pada iOS dan Android, gaya yang identik jarang diperlukan. Mereka memerlukan niat yang konsisten. Token visual yang sama masih dapat memerlukan padding yang berbeda, penempatan ikon, atau mode pilihan.

Penyesuaian yang berguna termasuk:

  • Pada iOS: Berikan ruang pernapasan pada 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 Pada iOS Android
Penampilan terbuka Rasa Modal Rasa Spinner
Harapan ikon Seringkali lebih dekoratif Seringkali lebih fungsional
Issue jarak Tata letak tempat pengganti dapat terasa longgar Teks dapat terasa sempit

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

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

Alasannya adalah radius borda, jarak label, dan warna tempat penempatan lebih penting daripada pengaturan 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-beda di platform, dan tempat penempatan tidak dapat berperilaku seperti nilai yang valid.

Skenario Edge yang Berulang ini sangat mengganggu di iOS. Pengembang sering perlu memuat nilai picker dari server sambil mencegah entri tempat penempatan dari dipilih, namun bahan resmi sering tidak menangani jalur tersebut secara langsung. Diskusi komunitas menyoroti bahwanilai tempat penempatan dapat tetap 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 pilihan 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 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 format tersebut 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 library UI membuatnya mudah untuk menampilkan satu.

Polanya yang praktis:

  • Gunakan nilai sentinela kosong: Tetapkan nilai pengganti sebagai '' atau nilai aplikasi yang tidak valid lainnya.
  • Validasi sebelum mengirim: Tolak nilai kosong dalam validasi formulir, bukan hanya di UI.
  • Matikan aksi downstream: 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 !== '';

Lalu tutup tombol aksi Anda atau API panggilan dari kondisi tersebut 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: Buatlah bidang tersebut dapat dipahami oleh pembaca layar.
  • Tetapkan label yang eksplisit: “Country” is better than “Select”.
  • lebih baik daripada ." Test keadaan restorasi:
  • Buka kembali formulir dan pastikan item yang dipilih sebelumnya masih muncul dengan benar. Tulislah tes unit di sekitar logika yang dipicu oleh pilihan: menguji perilaku React secara unit 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. Tatal Pilih NativeBase sebagai permukaan input. Masukkan aturan yang sebenarnya ke dalam alur keadaan, validasi, dan 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 panggilan callback pilih yang rapuh dan pindahkan ke dalam efek yang dikendalikan keadaan, komponen menjadi lebih dapat diprediksi.

Untuk kodebase yang lebih tua, itu kerja sama yang sering cukup. Untuk alur-alur 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 perubahan JavaScript, CSS, salinan, konfigurasi, dan aset tanpa menunggu ulasan toko Capgo adalah patut dilihat. Ia memberikan Anda pembaruan hidup yang ditandatangani, kontrol rollout, perlindungan rollback, dan visibilitas rilis sehingga Anda dapat pulih lebih cepat ketika bug UI seperti regresi pilih melarikan diri ke produksi.

Pembaruan langsung untuk aplikasi Capacitor

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

dukungan manusia dari Martin

Mulai Sekarang

Terbaru dari Blog Kami

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