React Native中TextInput设autofocus时BottomSheet异常自动弹出问题
问题:react-native-bottom-sheet 因输入框 autofocus 导致异常自动弹出
我使用react-native-bottom-sheet实现分类选择功能,给金额输入框(Amount)设置autofocus属性后,BottomSheet会偶发自动弹出(首次打开页面时概率约2/5)。弹出时它显示在键盘后方,未遵循预设的屏幕中间停靠点,而是停在键盘上方一点。BottomSheet本应仅在点击分类输入框时才打开,进入页面时需保持隐藏。我尝试通过控制渲染变量避免初始渲染,但仍会出现短暂闪烁现象。

BottomSheet组件代码
const TransactionBottomSheet: React.ForwardRefRenderFunction<refProps, Props> = (props, ref) => { const { onSelect } = props; const sheetRef = useRef<BottomSheet>(null); const [data, setData] = useState<Transaction[]>(categoriesData); const [selectedCategory, setSelectedCategory] = useState<Category | null>(null); const openSheet = useCallback(() => { sheetRef.current?.expand(); }, []); const closeSheet = useCallback(() => { sheetRef.current?.close(); }, []); useImperativeHandle(ref, () => ({ openSheet: () => openSheet(), })); const setTypeData = (id: number) => { const types = transactionCategories[id].types ?? []; setData(Object.values(types)); }; const clearCategory = () => { setData(categoriesData); setSelectedCategory(null); }; const onRowPress = (item: Transaction | Category) => { if (!selectedCategory) { setTypeData(item.id); setSelectedCategory(item as Category); } else { onSelect(selectedCategory, item); closeSheet(); } }; const onClose = () => { setData(categoriesData); setSelectedCategory(null); }; const renderItem = ({ item }: { item: Transaction | Category }) => ( <TransactionRowSelect item={item} hideIcon={!!selectedCategory} onPress={onRowPress} /> ); const renderBackdrop = useCallback( (props) => <BottomSheetBackdrop {...props} disappearsOnIndex={-1} appearsOnIndex={0} />, [] ); return ( <BottomSheet ref={sheetRef} snapPoints={snapPoints} enablePanDownToClose index={-1} onClose={onClose} backdropComponent={renderBackdrop} handleStyle={styles.handle} > <Label style={styles.title}>{"Pick category"}</Label> {!!selectedCategory && ( <> <TransactionRowSelect item={selectedCategory} onPress={clearCategory} /> <Separator /> </> )} <BottomSheetFlatList data={data} keyExtractor={(item) => `${item.id}`} renderItem={renderItem} /> </BottomSheet> ); }; const styles = StyleSheet.create({ title: { textAlign: "center", fontSize: 16, fontWeight: "bold", paddingBottom: 10, backgroundColor: colors.grey3, }, handle: { backgroundColor: colors.grey3, borderTopLeftRadius: 10, borderTopRightRadius: 10, }, }); export default React.forwardRef(TransactionBottomSheet);
添加交易页面代码
const TransactionForm: React.FC<Props> = ({ navigation }) => { const [date, setDate] = useState(new Date()); const sheetRef = useRef<TransactionBottomSheetType>(null); const [category, setCategory] = useState<Category | null>(null); const [type, setType] = useState<Transaction | null>(null); const [amount, setAmount] = useState(""); const [description, setDescription] = useState(""); const [tryCreateNewTransaction, { isLoading }] = useCreateNewTransactionMutation(); const onAdd = async () => { Keyboard.dismiss(); try { if (type && category) { await tryCreateNewTransaction({ amount: Number(amount), description, date: formatIsoDate(date), user_id: 1, type_id: type.id, category_id: category.id, }).unwrap(); navigation.goBack(); } } catch (error) { Alert.alert("An error occurred while adding transaction", "Please try again"); } }; const onSelectCategory = (category: Category, type: Transaction) => { setCategory(category); setType(type); }; const setCategoryText = () => { if (!category && !type) { return ""; } return `${category?.label}, ${type?.label}`; }; const openSheet = () => { if (sheetRef?.current) { Keyboard.dismiss(); sheetRef?.current?.openSheet(); } }; return ( <View style={styles.container}> <DatePickerInput date={date} maximumDate={new Date()} onDateSelect={setDate} /> {/* 这是自定义样式的TextInput,此处设置了autofocus属性 */} <LabelInput value={amount} placeholder='Amount' onChangeText={setAmount} keyboardType='decimal-pad' style={styles.marginTop} icon={<FontAwesome5 name='coins' size={24} color={colors.greenMint} />} autoFocus /> {/* <InputErrorLabel text={errors.amount} isVisible={!!errors.amount} /> */} <TouchableOpacity onPress={openSheet}> <LabelInput value={setCategoryText()} icon={<MaterialIcons name='category' size={24} color={colors.greenMint} />} disabled placeholder='Category' style={styles.marginTop} inputStyle={styles.category} /> </TouchableOpacity> <TextBox placeholder='Transaction comment' style={styles.marginTop} numberOfLines={6} maxLength={300} value={description} onChangeText={setDescription} /> <CustomButton title='Submit' onPress={onAdd} style={styles.marginTop} /> <AppActivityIndicator isLoading={isLoading} /> <TransactionBottomSheet ref={sheetRef} onSelect={onSelectCategory} /> </View> ); }; export default TransactionForm; const styles = StyleSheet.create({ container: { flex: 1, paddingHorizontal: 16, paddingTop: 20, }, marginTop: { marginTop: 20, }, category: { color: colors.black, }, });
内容的提问来源于stack exchange,提问作者sofronijev
相关产品推荐
相关产品推荐

