メインコンテンツにスキップ

Native Base ピッカー: セットアップ、スタイリング & Android修正

React NativeでNative Base ピッカーを実装する方法。 セットアップ、状態、スタイリング、およびAndroidでonValueChangeバグの重要な修正をカバーするクイックガイド。

Native Base ピッカー: セットアップ、スタイリング & Android修正

React NativeチームはNativeBase ピッカーで同じ壁に当たったことは多くありません。 ドロップダウンがレンダリングされ、iOSは正常に動作し、Androidはビジネスロジックが実行されないのに機能するように見えます。 onValueChange __CAPGO_KEEP_0__

NativeBase ピッカーは、経験豊富な開発者を意識していないため、まだ驚くことがあります。その理由は、セットアップは簡単、スタイリングは管理可能ですが、生産性の高い信頼性は、Android固有のエラーを理解することによって決まります。Android固有のエラーは、ほとんどのガイドでは省略または言及されていません。

目次

NativeBase Pickerの使用開始

ピッカーは通常、スプリントの後半に追加されるコンポーネントです。国選択、ステータスフィールド、アポイントメントタイプ、発送オプション。プラットフォームの動作がUIに漏れ出すまで、小さく感じることがあります。

良いニュースは NativeBase Picker は、画面上に表示することが簡単です。は、iOS と Android に対してネイティブのピッカーをレンダリングするように設計され、古いNativeBase設定で廃止されたReact Nativeピッカーを置き換えるために作られました。これがなぜ、多くのレガシーコードベースが依然としてそれに頼っているからです。

A developer workspace featuring a laptop displaying React Native code next to a mobile app interface.

正常なReact Native設定でコンポーネントをインストールします。

NativeBaseをすでに使用しているプロジェクトの場合、主なタスクは、必要な基本要素をインポートし、初日から不要なラッパーロジックを避けることです。最初は、できるだけシンプルな可視ピッカーから始めましょう。

モバイルとハイブリッドスタックを横断して作業している場合、より広い環境であるようにReact codeがパッケージ化される方法を理解することも役立ちます。 ReactモバイルアプリワークフローでCapacitor。.ピッカーcodeは、知られているままですが、展開の期待は変わります。

基本的な例は次のようになります。

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

抽象化なしで最初のピッカーをレンダリングします。

最初のパスでは、次の2つの質問に答える必要があります。

  • 正しくレンダリングされるかどうか: フィールドがレイアウト内に表示され、スペースを尊重し、両方のプラットフォームで開くかどうかを確認したいと思います。
  • インポートパスが正しいですか? NativeBaseプロジェクトは、古いコンポーネントAPIと新しいコンポーネントAPIを混在させていることが原因で、よくある理由で失敗することがあります。
  • 選択された値が制御されているかどうか: プロトタイプを捨てて作った場合でも、 selectedValue stateから値を取得するようにしてください。制御されていないピッカーcodeは、後でデバッグするのが難しくなります。

実用的なルール: サーバーデータ、プレースホルダールール、アナリティクスハック、バリデーションを同じピッカーにマッピングするのではなく、まずコンポーネントを表示し、制御することから始めましょう。

その簡素化された基準は重要です。Androidが後で不正行為を始める場合、問題はフォームアーキテクチャ全体ではなく、ピッカーだけです。

Stateと選択の処理

ピッカーがレンダリングされたら、次の仕事は、それを有用にすることです。React Nativeでは、それを制御された入力として扱い、選択された値をコンポーネントのstateに保持することです。

標準的なパスは簡単です。現在の値を保存し、 useStateに渡します。 selectedValue、状態を更新します。 onValueChange他のフォームフィールドと同じように考えます。 React Native TextInput のパターンUI コントロールが異なっていても

値を制御する値を最初から使用します。

ここに示すのは、検証や副作用を追加する前に使用するべき clean バージョンです。

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 は、予測可能な真実の源を提供します。UI は role、そして、すべての下流の関数は同じ状態から読み取ることになります。

選択ロジックを小さくテストしやすくします。

開発者がオーバーロードすることが多いのは、 onValueChange。データを取得し、複数の状態スライスを変更し、ナビゲーションをトリガーし、分析をログするinline関数です。ピッカーの動作が失敗すると、デバッグが苦痛になります。

より良いパターンは、値の保存と副作用を分離することです。

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

この構造体は、2つの便利な機能を実行します:

  1. ピッカーは選択状態の更新のみに責任を負わせるようにします。
  2. アプリの動作は useEffectに移動します。ここでは、テストや推論を行うことができます。

フォームコンポーネントが、選択された値を信頼できるようにアプリに伝えることができない場合、すべての副作用は疑問視されます。

Androidでは、NativeBase ピッカーの意図されたイベントフローが常に機能しないことがあります。これは、選択された値がアプリに伝えられないときに特に重要です。

AndroidのonValueChange バグのトラブルシューティング

この部分は、ほとんどの記事が省略しています。NativeBase ピッカーはAndroid上で正常に表示されるかもしれませんが、必要な時には機能しないことがあります。

コミュニティドキュメントでは、古いピッカー実装に関するクロスプラットフォームの分割について説明しています。 Androidでは onValueChangeがカスタム関数にアタッチされていないのに対し、iOSではがカスタム関数にアタッチされ、そしてその失敗は Android上で100%の機能不全が発生し、Androidデバイス上で0%の成功率で機能をトリガーするにもかかわらず、同様のcode実装 文書化された報告書の中にあります。同様のドキュメントは開発者をワークアラウンドまたは移行の方向に導き、NativeBase 3.0 Select コンポーネントが 98%の機能トリガー成功率を両方のプラットフォームでテスト環境で達成 比較検討すると、NativeBase ピッカー ドキュメントと移行コンテキスト NativeBase ピッカー コンポーネントのAndroidにおける一般的なバグとその提案された解決策を示すインフォグラフィック。.

Whatが実際にAndroidで破壊される

実際の理由は実装詳細です。Android上のNativeBase ピッカーはnativeスピナーに依存し、そのレイヤーは多くの開発者が期待するように、ラッパーにイベントリスナーを伝播しません。iOS上ではモーダルベースの動作はイベントシステムにバインドされ正しく動作します。

このバグはなぜデュースティックに感じられるのか。UIが見えます。オプションを開くことができます。選択可能なアイテムを表示することもできます。ですが、ビジネス関数は実行されません。

典型的な失敗パターンは次のようになります。

iOS上では、意図どおりに動作するかもしれません。Android上ではピッカーはレンダリングされますが、関数は実行されません。

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

Android上でNativeBase ピッカーの機能不全とその解決策を解説するインフォグラフィックです。

A productionで機能するワークアラウンド

最も信頼できるワークアラウンドは、外観ではなく、設計上のものです。ピッカーのインタラクションは、選択された値を保存することに焦点を当て、ピッカーのハンドラーの外側の状態の変更に反応します。

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、ピッカーのイベントペイロードだけではありません。
  • 副作用は明確になります: APIの呼び出し、依存フィールドの更新、トラッキングは、脆弱なUIコールバック内に存在しなくなります。
  • codeを置き換えることが容易になります: NativeBase Pickerから移行する場合、ビジネスロジックのほとんどが、変更なしで生き残ります。

Android重視のプロジェクトの場合、また、既存のアプリにnativeパッケージングの複雑さがある場合、実機で早期にテストすることをお勧めします。 Android用のCapacitorアプリのセットアップ.

Select への移行は、より綺麗な決定です

ピッカーがチェックアウト、オンボーディング、または規制されたデータ入力などの重要なワークフロー内に位置している場合、古い動作を修正する代わりに、NativeBase 3.0 への移行が長期的にはより安全な選択肢となる場合があります。 Select バグは単に不便なだけでなく、ビジネスロジックを安全に配置できる場所を変更します。

古いピッカーを維持する場合は、それをUIシェルとして最小限の責任を持たせるようにしてください。この考え方は、静かにAndroidのバグを防ぐのに役立ちます。

ピッカー コンポーネントのスタイリングとテーミング

ピッカーが機能している場合でも、他のアプリのデザインに合わない場合は、完成感が欠けます。NativeBaseは、コントロールが意図的に感じられるようにするための十分なハックを提供しますが、最も綺麗な結果は、ピッカーを直接戦うのではなく、ピッカーの周囲のコンテナをスタイリングすることによって得られます。

スマートフォンを握った手が、旅行予約アプリのNativeBaseピッカー ドロップダウンメニューを表示している。

ピッカーのスタイリングよりもコンテナのスタイリングを優先する

ピッカー自体は、部分的にネイティブレンダリングによって制限されています。コンテナは、ピッカーのスペーシング、ボーダータイプ、レイアウトリズムの制御に比べて、はるかに多くの制御を提供します。

実践的なパターン:

このアプローチは、テーマのオーバーライドを過度にエンジニアリングすることなく、ほとんどの場合に目的を達成するのに役立ちます。

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

移動

プラットフォームに合わせた表示を使用する

iOSとAndroidはほとんど同じスタイリングが必要ではない。意図が一貫している必要がある。同じ視覚的トークンでも、異なるパディング、アイコンの配置、ピッカーのモードが必要になる場合がある。

有用な調整には含まれる

  • iOSの場合: フィールドに余白を与え、モーダル表示が周囲のラベルとどのように関係しているかを注意する
  • Androidの場合: テキストのクリッピングやデフォルトのスピナー高さを複数のデバイスで確認する
  • 両方の場合: プレースホルダーテキストが実際の選択と視覚的に区別できるようにする

短い比較が役立つ

懸念 iOS Android
オープンベHAVIOR モーダルフィール スピナーフィール
アイコンの期待 しばしば装飾的な しばしば機能的な
スペーシングの問題 プレースホルダーライアウトがゆるい テキストがぎこちなく感じる

UIにグラデーション、レイヤードカード、または高コントラストの表面が含まれている場合、ピッカー・ワッパーを同じ処理で他のインターフェイスの場所と同様に揃えます。 React Nativeの線形グラデーションUIワークのパターンと同様に.

デザインノート: ユーザーは、ドロップダウン自体よりも、フォーム内で閉じたフィールドがどのように収まるかでピッカーを評価します。

したがって、ボーダーラジウス、ラベルスペーシング、プレースホルダーカラーは、エキゾチックなピッカーのカスタマイズよりも重要です。

高度なシナリオとベストプラクティス

ほとんどのピッカーのバグは、コンポーネントがプロトタイプフェーズを超えた後に出現します。問題は、オプションがサーバーから取得され、プラットフォームごとに検証ルールが異なり、プレースホルダーが有効な値として振る舞えない場合に始まります。

iOS上で特に面倒なエッジケースが繰り返し発生します。開発者は、プレースホルダー入力を選択できないようにサーバーからピッカー値をロードする必要がありますが、公式のマテリアルはそのパスを直接扱っていません。コミュニティの議論では、 プレースホルダー値がiOS上で選択可能であることが問題となっています。これが原因となって、実際のアプリでは不一致の動作が生じていることが、この React Nativeコミュニティの議論でサーバーからロードされたピッカー値とプレースホルダーの選択可能性について議論されています。.

NativeBaseで使用するダイナミックピッカーの4ステップのデータフロープロセスを示す図。

サーバーからピッカーのオプションを安全にロードする

最もよく見る間違いは、取得したデータを即座にピッカーとして扱うことです。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>
  );
}

そのフォーマット手順は、安定した契約を与えます。ピッカーには、APIの内部構造を知る必要がありません。

iOS上のプレースホルダーの選択を防止する

最も安全なルールは単純です。プレースホルダーを実際のオプションとして扱うのではなく、UIライブラリがそれをレンダリングするのを容易にしている場合でも、実際のオプションとして扱わないことです。

実用的パターン:

  • 空のシーケンス値を使用する: プレースホルダー値を '' または、他の無効なアプリケーション値として保持します。
  • 送信前に検証する: 空の値をフォーム検証で拒否するのではなく、UIでだけ拒否するのではなくします。
  • 下流のアクションを無効にする: プレースホルダー値が選択されている限り、送信ボタンを有効にするのを待つ。

厳格なフローでは、プレースホルダーが選択されている限り、ヘルプテキストをレンダリングする:

const isValidSelection = selectedCategory !== '';

Then ですべてのアクションボタンをゲートするか、APIの呼び出しをその条件から外すのではなく、ピッカーの表示を信頼するのではなく。

アクセシビリティと生産性の習慣

ピッカーは、ネイティブの見た目でアクセシビリティのレビューを通過することがよくありますが、まだ明確なラベル付けと予測可能な状態が必要です。

すぐに効果が現れる習慣は少しだけあります。

  • アクセシビリティのラベルを追加する: スクリーンリーダーにフィールドを理解できるようにする:
  • ラベルを明確にする: “国”は“選択”より良いです。
  • 状態の復元をテストする: フォームを再度開いて、以前選択されたアイテムが正しく表示されることを確認する。
  • 選択に依存するロジックに関するユニットテストを書く: UI外側のロジックは最も重要ですが 単位テストのReact動作 状態遷移を保護するためにあなたを助けます。

Picker自体はあまりビジネスクリティカルではありません。背後にある状態の変更はそうです。

ダイナミックフォームを安定させるのはその考え方だ。NativeBase Pickerを入力面として扱い、実際のルールはstate、バリデーション、サブミッションフローに置く。

結論

NativeBase ピッカーは、どこで機能が途切れるかを理解している場合にまだ有用です。セットアップは簡単で、スタイリングは実行可能で、サーバーからドライブされるオプションリストは管理可能です。ただし、Android イベントハンドリングは大きな罠です。ビジネスロジックを脆弱なピッカーのコールバックから外し、状態駆動のエフェクトに移動すると、コンポーネントは予測可能になります。

Capgoの古いコードベースでは、代替手段はよく機能します。 重要なフローでは、Capgoに移行する Select Native Base ピッカーは、通常はより良い投資です。どちらの場合も、キーは同じです。ピッカーを信頼してはいけません。なぜなら、ピッカーがレンダリングされるからです。


アプリを Capacitor または Electron で開発しているチームが、JavaScript、CSS、コピー、設定、資産の修正をストアのレビューを待たずにプッシュしたい場合。 Capgo UI バグのようなピッカーのリグレッションが生産環境に逃げ込むときに、UI バグを速やかに回復できるように、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの回復が可能なように、生産環境にリリースするときに、UI バグの

Live updates for Capacitor apps

Capgoのウェブ層のバグが生じた場合、Capgoを通じて修正を配信し、App Storeの承認待ちの日数を待つのではなくします。ユーザーはバックグラウンドで更新を受け取り、ネイティブの変更は通常のレビュー経路に残ります。

マーティンから人間のサポートを受けます。

スタートする

最新のブログ記事

Capgoは、プロフェッショナルなモバイルアプリを作成するために必要な最良の洞察を提供します。