React Native中TouchableOpacity的onPress在子组件上失效求助
问题原因
你遇到的问题是因为react-native-paper的TextInput是自带交互的组件,它会拦截触摸事件,导致外层的TouchableOpacity只能接收到组件边缘(Animated.View的空白区域)的点击,点击TextInput本身时事件被组件消耗,外层onPress无法触发。
修复方案
方案1:给SearchComponent传递点击回调,在TextInput上触发
修改SearchComponent.js,接收父组件的点击回调并绑定到TextInput的触摸事件:
import React, { useEffect, useState } from 'react' import { Animated } from 'react-native' import { TextInput } from 'react-native-paper'; export default function SearchComponent({ expanded = false, onPress }) { const [search, setSearch] = useState('') const [bottom] = useState(new Animated.Value(0)) useEffect(() => { Animated.timing(bottom, { toValue: !expanded ? 80 : 10, duration: 150, useNativeDriver: false }).start(); }, [expanded, bottom]); return ( <Animated.View style={{ bottom, backgroundColor: 'red', borderWidth: 3, borderColor: 'red' }}> <TextInput placeholder='Search' defaultValue={search} onChangeText={e => setSearch(e)} style={{ backgroundColor: 'white', borderRadius: 20 }} // 触发父组件的点击逻辑 onTouchEnd={onPress} /> </Animated.View> ) }
修改App.js,给SearchComponent传递onPress参数:
<View style={styles.searchContainer} > <TouchableOpacity onPress={() => setExpanded(!expanded)}> <SearchComponent expanded={expanded} onPress={() => setExpanded(!expanded)} /> </TouchableOpacity> </View>
方案2:将TouchableOpacity移到SearchComponent内部
把触摸容器放到组件内部,确保整个搜索区域都能响应点击,同时保留TextInput的输入功能:
import React, { useEffect, useState } from 'react' import { Animated, TouchableOpacity } from 'react-native' import { TextInput } from 'react-native-paper'; export default function SearchComponent({ expanded = false, onPress }) { const [search, setSearch] = useState('') const [bottom] = useState(new Animated.Value(0)) useEffect(() => { Animated.timing(bottom, { toValue: !expanded ? 80 : 10, duration: 150, useNativeDriver: false }).start(); }, [expanded, bottom]); return ( <Animated.View style={{ bottom, backgroundColor: 'red', borderWidth: 3, borderColor: 'red' }}> <TouchableOpacity onPress={onPress} style={{flex: 1}} activeOpacity={1} // 避免触摸时改变TextInput透明度 > <TextInput placeholder='Search' defaultValue={search} onChangeText={e => setSearch(e)} style={{ backgroundColor: 'white', borderRadius: 20 }} /> </TouchableOpacity> </Animated.View> ) }
此时App.js可以简化,移除外层的TouchableOpacity:
<View style={styles.searchContainer} > <SearchComponent expanded={expanded} onPress={() => setExpanded(!expanded)} /> </View>
额外优化(可选)
如果希望点击TextInput时既触发展开/收起,又能自动聚焦输入,可以给TextInput添加ref并手动聚焦:
// 在SearchComponent中添加ref const inputRef = useRef(null); // 修改onTouchEnd逻辑 onTouchEnd={() => { onPress(); inputRef.current?.focus(); }} // 给TextInput绑定ref <TextInput ref={inputRef} ... />
内容的提问来源于stack exchange,提问作者noor.soreti
相关产品推荐
相关产品推荐

