如何无需open、setOpen属性使用react-native-dropdown-picker组件
问题解答
不存在完全不传open、setOpen属性、也不声明对应状态就能正常使用DropDownPicker的方案。
这两个属性是react-native-dropdown-picker的强依赖必填属性,组件内部没有内置下拉展开/收起的自管理状态逻辑,面板的显隐、点击外部收起、多下拉互斥等核心逻辑都依赖外部传入的状态和更新方法驱动,缺省传入会直接导致组件功能异常。
如果只是不想在业务代码里重复写useState声明的样板代码,可以通过封装通用自定义Hook的方式把状态逻辑抽离,业务侧使用时不需要单独维护open状态,使用体验和组件自管理状态基本一致:
实现步骤
- 先封装可复用的下拉状态管理Hook
// hooks/useDropdownPicker.js import { useState, useMemo } from 'react'; export default function useDropdownPicker(initialOpen = false) { const [open, setOpen] = useState(initialOpen); // 直接打包组件需要的open相关props,使用时直接展开即可 const bindProps = useMemo(() => ({ open, setOpen }), [open]); return { open, setOpen, bindProps }; }
- 在业务代码中直接调用Hook使用,不需要单独声明open相关的useState
// 你的表单组件内 // 只需要一行调用,不需要单独写const [openDropdown, setOpenDropdown] = useState(false) const couponDropdown = useDropdownPicker(); <Controller control={control} name={EPaymentFormField.PROMOTION_COUPON_ID} render={({ field: { value, onChange } }) => { const handleChange = (callback) => { onChange(callback()); }; return ( <DropdownPicker placeholder={t('paymentDetail_coupon_label', { numOfAvailableCoupons: numOfAvailableCoupons, numOfTotalCoupons: numOfTotalCoupons, })} {...couponDropdown.bindProps} value={value} setValue={handleChange} items={dropdownData} multiple={false} /> ); }} />
注意事项
- 同一个页面存在多个DropDownPicker实例时,每个实例单独调用一次
useDropdownPicker()即可,各实例状态独立不会冲突 - 不要尝试给
open传固定布尔值、给setOpen传空函数绕开必填校验,会触发下拉面板无法展开、选中选项后面板不关闭、布局错位等异常 - 该组件从v5大版本开始就强制采用受控模式管理展开状态,官方没有提供非受控的使用模式,所有无需手动写useState的方案本质都是把状态逻辑抽离到了封装层,并没有绕过组件的必填属性要求
内容的提问来源于stack exchange,提问作者Mingy Woo
相关产品推荐
相关产品推荐

