당신은 리액트 네이티브 팀이 네이티브 베이스 픽커와 마주하는 벽을 여러 번 만났을 것입니다. 픽커가 렌더링되며 보이는 것처럼 iOS는 정상 작동하고, Android는 당신의 논리와 무관합니다. 충돌이 없습니다. 경고도 없습니다. 단지 기능적으로 보이는 픽커가 있습니다. 그러나 당신의 비즈니스 논리가 실행되지 않습니다. onValueChange 마틴 도나디우
NativeBase Picker는 경험 많은 개발자들을 놀라게 하는 이유입니다. 설정은 간단하고 스타일링은 관리가 가능하지만, 프로덕션의 신뢰성은 Android에 특화된 오류를 이해하는 데에 달려 있습니다. 그 오류는 대부분의 가이드가 생략하거나 언급하지 않습니다.
내용목록
- NativeBase Picker를 사용하기
- 상태 바인딩 및 선택 처리
- Android onValueChange 버그를 해결하는 방법
- UI 구성 요소의 스타일링과 테마 설정
- 고급 시나리오와 최적화된 방법
- 결론
NativeBase 픽커와 함께 시작하기
픽커는 일반적으로 스프린트의 마지막 단계에 추가되는 컴포넌트 중 하나입니다. 국가 선택기, 상태 필드, 약속 유형, 배송 옵션. 플랫폼 동작이 UI에 유입될 때까지 작게 느껴집니다.
좋은 소식은 NativeBase Picker 화면에 나타날 수 있는 것이 쉽습니다. iOS 및 Android에서 원시 픽커를 렌더링하고 React Native Picker가 더 이상 사용되지 않는 NativeBase의 이전 설정을 대체하기 위해 만들어졌기 때문에, 많은 레거시 코드베이스가 여전히 그것에 의존하고 있습니다.

일반적인 React Native 설정에서 컴포넌트를 설치합니다.
NativeBase를 이미 사용 중인 프로젝트의 경우, 주된 작업은 올바른 원초체를 가져오고 일단의 불필요한 wrapper 논리를 피하는 것입니다. 가장 단순한 표시되는 픽커부터 시작하세요.
모바일 및 하이브리드 스택을 동시에 작업하는 경우, React code가 더 넓은 환경인 React Native의 패키징 방식에 대한 이해도 도움이 됩니다. React Native 앱의 모바일 워크플로우에서 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>
);
}
추상화 없이 첫 번째 픽커를 렌더링합니다.
첫 번째 패스는 두 가지 질문에만 답해야 합니다:
- 정확하게 렌더링되는지 확인합니다: 필드가 레이아웃 내에 나타나고 간격을 존중하며, 양쪽 플랫폼에서 열리는지 확인합니다.
- 정확한 import 경로가 맞는지 확인하세요: NativeBase 프로젝트는 보통 기존과 새로운 컴포넌트 API를 섞어서 사용하는 경우에 실패합니다.
- 선택된 값이 제어되는지 확인하세요: 조립품으로 사용하는 프로토타입이라도,
selectedValue상태에서 값을 가져오세요. code가 추후 디버깅이 어려워질 수 있습니다.
실용적인 규칙: 서버 데이터, placeholder 규칙, 분석 Hook, 유효성 검사 Hook을 모두 picker에 넣지 마세요. 먼저 컴포넌트를 제어하는 picker를 만드세요.
기본적인 baseline이 중요합니다. Android가 나중에 이상하게 동작할 때, 전체 폼 아키텍처가 문제가 아니라는 것을 알 수 있습니다. picker가 문제입니다.
상태와 선택을 처리하는 방법
picker가 렌더링된 후, 다음 작업은 picker를 유용하게 만드는 것입니다. React Native에서, 그것은 선택된 값을 컴포넌트 상태에 저장하는 것과 같습니다.
표준 경로는 간단합니다. 현재 값을 저장하고 useState에 전달하세요. selectedValue그리고 상태를 업데이트합니다. onValueChange이것은 다른 형식 필드와 같은 마음가짐을 사용하는 것과 같습니다. React Native TextInput 패턴UI 제어 요소가 다르더라도
제어된 값을 사용하세요.
이것이 유효성 검사나 부수 효과를 추가하기 전에 사용할 수 있는 깨끗한 버전입니다.
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. 그들은 데이터를 가져와, 여러 상태 조각을 변형하고, 내비게이션을 트리거하고, 분석 로그를 기록합니다.
한 줄 함수 내에서. 픽커 동작이 실패하면 디버깅이 고통스럽습니다.
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>
</>
);
}
이 구조는 두 가지 유용한 일을 수행합니다:
- 픽커가 선택 상태를 업데이트하는 것에만 책임을 지도록 만듭니다.
- 앱의 동작을
useEffect에서 테스트하고 추론할 수 있도록 옮깁니다.
폼 컴포넌트가 선택된 값이 무엇인지 신뢰할 수 없다면, 모든 부수 효과가 의심스럽게 됩니다.
이 점은 안드로이드에서 특히 중요합니다. NativeBase Picker의 의도된 이벤트 흐름이 항상 유지되지 않기 때문입니다.
안드로이드 onValueChange 버그를 해결하는 방법
이 부분은 대부분의 기사에서 생략됩니다. NativeBase Picker는 안드로이드에서 보이는 동안 정확한 순간에 실패할 수 있습니다.
커뮤니티 문서에서는 이전의 픽커 구현에 대한 설명이 있습니다. 이 설명은 실제로 플랫폼 간의 분리를 설명합니다. 안드로이드에서는 onValueChange를 호출하지 않습니다. 반면, iOS에서는를 호출하고, 이 실패는 100% functional disparity on Android with a 0% success rate for function triggering on Android devices despite identical code implementation 문서화된 보고서에서 동일한 __CAPGO_KEEP_0__ 구현을 사용함에도 불구하고 Select 문서화된 보고서에서 동일한 __CAPGO_KEEP_0__ 구현을 사용함에도 불구하고 NativeBase 3.0 구성 요소는 테스트 환경에서 98%의 기능 트리거링 성공률을 달성했습니다. NativeBase Picker 구성 요소의 문서화된 설명서와 마이그레이션 컨텍스트에서 설명된 것과 비교하여 NativeBase Picker 구성 요소의 안드로이드 버그와 제안된 해결책을 설명하는 인포그래픽입니다..

실질적인 이유는 구현 세부 사항입니다. 안드로이드에서 NativeBase Picker는 네이티브 스플리너에 의존하고, 그 층은 wrapper에 이벤트 리스너를 전파하지 않습니다. 많은 개발자들이 기대하는 것과 달리. iOS에서 모달 기반 동작은 이벤트 시스템에 바인딩이 됩니다.
이 버그가 유혹적인 이유는 무엇입니까?
UI를 볼 수 있습니다. 옵션을 열 수 있습니다. thậm chí 선택 가능한 항목을 선택할 수 있습니다. 그러나 비즈니스 함수는 실행되지 않습니다.
일반적인 실패 패턴은 다음과 같습니다.
<Picker
selectedValue={status}
onValueChange={(value) => {
setStatus(value);
saveStatusToApi(value);
trackSelection(value);
updateDependentFields(value);
}}
>
iOS에서 이 동작은 의도한대로 작동할 수 있습니다. 안드로이드에서 픽커는 렌더링을 할 수 있지만 함수는 실행되지 않습니다.
A 프로덕션에서 유지되는 대안
가장 신뢰할 수 있는 대안은 구조적인 대안이 아닌 외관적인 대안입니다. 선택한 값을 저장하는 데 집중하는 픽커 상호 작용을 유지하고, 픽커 핸들러 외부의 상태 변경에 반응하세요.
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-heavy 프로젝트의 경우, 실제 기기에서 테스트를 일찍 시작하는 것도 추천합니다. 특히 이미 NativeBase Picker를 사용하는 앱이 NativeBase Picker를 사용하는 앱과 유사한 네이티브 패키징 복잡성을 가지고 있다면. Android setup for Capacitor apps.
Select로 마이그레이션하는 것이 더 깨끗한 결정입니다.
픽커가 체크아웃, 온보딩, 또는 규제 데이터 입력과 같은 крит적 워크플로에 위치한다면, 이전 동작을 대체하는 데 대한 노력은 그만한 가치가 아닐 수 있습니다. 그 시점에서 NativeBase 3.0으로 이동하는 것이 보통 더 안전한 장기적인 결정입니다. Select 버그는 단순히 불편함만이 아닙니다. 그것은 비즈니스 로직을 안전하게 위치할 수 있는 곳을 변경합니다.
픽커를 유지하면 그것을 UI 셸로 간주하고 최소한의 책임을 지도록 하세요. 그 마음가짐은 많은 silent Android regressions를 방지합니다.
픽커 컴포넌트 스타일링 및 테마링
픽커가 작동하더라도 앱의 나머지 부분과 일치하지 않으면 아직도 완성되지 않은 느낌이 듭니다. NativeBase는 컨트롤이 의도된 것처럼 느끼게 해주는 충분한 hook를 제공하지만, 픽커를 직접 싸우기보다 픽커 주변의 컨테이너를 스타일링하는 것이 가장 깨끗한 결과를 얻는 경우가 많습니다.
여행 예약 앱을 보여주는 스마트폰을 잡고 있는 손.

픽커 자체는 부분적으로 네이티브 렌더링에 의해 제한됩니다. wrapper는 픽커와 관련된 스페이싱, 경계 처리, 레이아웃 리듬에 대한 더 많은 제어권을 제공합니다.
실용적인 패턴:
그 접근 방식은 일반적으로 theme overrides를 과도하게 엔지니어링하지 않고 대부분의 방법으로 그곳까지 가져옵니다.
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 | 안드로이드 |
|---|---|---|
| 열기 동작 | 모달 느낌 | 스피너 느낌 |
| 아이콘 기대 | 많은 경우에 더 장식적인 | 많은 경우에 더 기능적인 |
| 간격 문제 | 프레이스 홀더 레이아웃이 느슨한 느낌 | 텍스트가 느슨한 느낌 |
UI에 그라디언트, 층식 카드, 또는 고대비 표면이 포함되어 있다면, 픽커 wrapper를 동일한 처리를 사용하는 인터페이스에서 사용하는 것과 같이 동일한 처리를 사용하세요. React Native 선형 그라디언트 UI 작업에서 사용하는 패턴과 유사하게 React Native 선형 그라디언트 UI 작업.
설계 주의사항: 사용자는 픽커 자체보다는 닫힌 필드가 폼 내부에 어떻게 위치하는지에 더 많은 판단을 내립니다.
그것이为什么 반경, 레이블 간격, 플레이스 홀더 색상이 더 중요한 것인지 이유입니다.
고급 시나리오 및最佳 관행
픽커 버그가 대부분 프로토 타입 단계를 벗어나면 나타납니다. 문제는 옵션이 서버에서 오고, 유효성 검사 규칙이 플랫폼에 따라 다르며 플레이스 홀더가 유효한 값처럼 행동할 수 없을 때 시작됩니다.
iOS에서 특히 짜증나는 반복되는 에지 케이스는 개발자가 서버에서 픽커 값을 로드하는 동안 플레이스 홀더 항목이 선택할 수 없도록 방지해야 한다는 것입니다. 그러나 공식 자료가 그 경로를 직접 다루지 않는 경우가 많습니다. 커뮤니티 토론은 iOS에서 플레이스 홀더 값이 선택할 수 있는 경우가 발생한다는 점을 강조합니다.이것이 서버 로드 픽커 값 및 플레이스 홀더 선택에 대한 React Native 커뮤니티 토론에 대해 언급한 것과 같습니다. NativeBase에서 동적 픽커를 사용하는 4단계 데이터 흐름 프로세스를 minh họa하는 다이어그램입니다..

나는 가장 자주 보는 실수는 fetched 데이터를 즉시 픽커 준비 상태로 간주하는 것입니다. __CAPGO_KEEP_0__ 응답과 컴포넌트 사이에 작은 변환层를 유지하세요.
The mistake I see most often is treating fetched data as immediately picker-ready. Keep a small transformation layer between your API response and the component.
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>
);
}
그 형식 단계는 안정적인 계약을 제공합니다. PICKER는 API의 내부 형태를 알 필요가 없습니다.
iOS에서 placeholder 선택 방지
가장 안전한 규칙은 간단합니다. placeholder를 실제 옵션으로 다루지 마십시오. UI 라이브러리가 그것을 렌더링하기 쉽게 만드는 것과는 다릅니다.
실용적인 패턴:
- 빈 보초 값 사용: __CAPGO_KEEP_0__의 placeholder 값은
''또는 다른 유효하지 않은 애플리케이션 값입니다. - 유효성 검사하기 전에: UI에서만 아니라, 폼 유효성 검사에서 빈 값을 거부하십시오.
- 다운스트림 액션 비활성화: __CAPGO_KEEP_0__의 placeholder 값이 선택된 경우 submit 버튼을 비활성화하십시오.
더 엄격한 흐름에서, placeholder가 선택된 경우 helper 텍스트 렌더링:
const isValidSelection = selectedCategory !== '';
그런 다음 액션 버튼을 게이트하거나 API 호출을 해당 조건 대신에 중단하세요.
접근성 및 생산 습관
픽커는 종종 접근성 검토를 통과하지만, 그들은 명확한 레이블링 및 예측 가능한 상태가 필요합니다.
몇 가지 습관이 빠르게 성과를 낼 것입니다:
- 접근성 레이블을 추가하세요: 스크린 리더가 필드를 이해할 수 있도록 하세요.
- 레이블을 명확하게 유지하세요: “Country” is better than “Select”.
- 테스트 상태 복원: 폼을 다시 열고 이전에 선택한 항목이 올바르게 나타나는지 확인하세요.
- 선택에 의한 논리와 관련된 단위 테스트를 작성하세요: UI 외부의 논리가 가장 중요합니다. 단위 테스트 React 동작 상태 전환을 보호하는 데 도움이 됩니다.
픽커 자체는 거의 비즈니스 крит적인 경우가 없습니다. 일반적으로 뒤에 있는 상태 변경이 중요합니다.
동적 폼을 안정적으로 유지하는 데 필요한 마음-set입니다. NativeBase Picker를 입력 표면으로 다루세요. 실제 규칙은 상태, 유효성 검사 및 제출 흐름에 두세요.
결론
NativeBase Picker는 깨지지 않는다는 것을 이해하면 여전히 유용합니다. 설정은 간단하고 스타일링은 가능하며 서버에서 옵션 목록을 관리하는 것은 가능합니다. 그러나 Android 이벤트 처리는 중요한 함정입니다. 프래그먼트 픽커 콜백에서 비즈니스 로직을 제거하고 상태 기반 효과로 옮기면 컴포넌트가 훨씬 더 예측 가능해집니다.
구성된 코드베이스의 경우, 이 대안은 종종 충분합니다. 그러나 중요한 흐름의 경우, Select 는 일반적으로 더 좋은 투자입니다. 어느 쪽이든, 핵심은 동일합니다. 픽커가 렌더링되는 것만으로는 신뢰하지 마세요.
If your team ships Capacitor or Electron apps and wants to push JavaScript, CSS, copy, config, and asset fixes without waiting for store review, Capgo 는 관심사입니다. signed live updates, rollout control, rollback protection, 및 release visibility를 제공하여 UI 버그와 같은 픽커 회귀가 프로덕션으로 도망치면 더 빠르게 복구할 수 있도록 해줍니다.