React Native TextInput onFocus 不允许其他子组件的onPress
React Native TextInput onFocus does not allow onPress of other child components
嵌套的TextInput组件不允许调用其他组件的onPress函数。仅当 TextInput 未获得焦点时,onPress 才能正常工作。
React 本机版本:0.66.3
这是我的代码
export const Component = (props): JSX.Element {
const { searchText, onChangeSearchText, onClearSearchText } = props
const [searchViewFocused, setSearchViewFocused] = useState<boolean>(false)
const searchIcon = searchViewFocused ? "searchActive" : "searchInactive"
const cancelIcon = searchViewFocused ? "cancelActive" : "cancelInactive"
return (
<View style={styles.searchBoxContainer}>
<View style={[styles.searchBox, searchViewFocused && styles.searchBarActive]}>
<Icon styles={styles.searchIcon} icon={searchIcon} />
<TextInput
style={styles.searchInput}
onChangeText={onChangeSearchText}
value={searchText}
onFocus={() => setSearchViewFocused(true)}
onBlur={() => setSearchViewFocused(false)}
autoCompleteType={"off"}
numberOfLines={1}
/>
{searchText !== "" && (
<Pressable style={styles.clearIcon} onPress={onClearSearchText}>
<Icon icon={cancelIcon} />
</Pressable>
)}
</View>
</View>
)
})
附件是
的图片
预期。
VS
问题
当在聚焦状态下按下十字图标时,textInput 没有聚焦我想要实现的是搜索文本被清除并且输入保持聚焦。
注意:当输入未聚焦时,onPress 工作得很好
感谢任何帮助。谢谢!
PS:尝试了 TouchableOpacity 并且我还尝试将组件包装在 ScrollView 中以使用 keyboardShouldPersistTaps='handled',如 SO 答案之一所述,但没有成功。
您正在根据 TextInput 是否具有焦点来设置整个组件的焦点。由于清除按钮在文本输入之外,按下它会导致组件失去焦点。
一种解决方案是将 TextInput 实例存储在 ref 中。当按下清除按钮时,您可以重新聚焦文本输入。我在下面复制了您的组件并添加了一些新行,这些行已在注释中标记。
export const Component = (props): JSX.Element {
const { searchText, onChangeSearchText, onClearSearchText } = props
const textInputRef = useRef(null); // new
const [searchViewFocused, setSearchViewFocused] = useState<boolean>(false)
const searchIcon = searchViewFocused ? "searchActive" : "searchInactive"
const cancelIcon = searchViewFocused ? "cancelActive" : "cancelInactive"
const onClear = () => {
onClearSearchText();
textInputRef.current?.focus();
} // new
return (
<View style={styles.searchBoxContainer}>
<View style={[styles.searchBox, searchViewFocused && styles.searchBarActive]}>
<Icon styles={styles.searchIcon} icon={searchIcon} />
<TextInput
ref={textInputRef} // new
style={styles.searchInput}
onChangeText={onChangeSearchText}
value={searchText}
onFocus={() => setSearchViewFocused(true)}
onBlur={() => setSearchViewFocused(false)}
autoCompleteType={"off"}
numberOfLines={1}
/>
{searchText !== "" && (
<Pressable style={styles.clearIcon} onPress={onClear}> // calls new function
<Icon icon={cancelIcon} />
</Pressable>
)}
</View>
</View>
)
})
找到一个解决方法是将整个组件包装到 ScrollView 中并添加道具 keyboardShouldPersistTaps='handled'
之前,我将 Component
中的视图设为 ScrollView 并添加了 keyboardShouldPersistTaps='handled'
,但没有用
export const Component = (props): JSX.Element {
...
return (
<ScrollView contentContainerStyle={styles.searchBoxContainer}
keyboardShouldPersistTaps='handled'>
...
</ScrollView>
)
})
关键是将整个组件包裹在 ScrollView 中,
这是有效的方法:
<ScrollView keyboardShouldPersistTaps='handled'>
<Component {...props}/>
</ScrollView>
我猜这是一个愚蠢的错误,但值得指出!
嵌套的TextInput组件不允许调用其他组件的onPress函数。仅当 TextInput 未获得焦点时,onPress 才能正常工作。
React 本机版本:0.66.3
这是我的代码
export const Component = (props): JSX.Element {
const { searchText, onChangeSearchText, onClearSearchText } = props
const [searchViewFocused, setSearchViewFocused] = useState<boolean>(false)
const searchIcon = searchViewFocused ? "searchActive" : "searchInactive"
const cancelIcon = searchViewFocused ? "cancelActive" : "cancelInactive"
return (
<View style={styles.searchBoxContainer}>
<View style={[styles.searchBox, searchViewFocused && styles.searchBarActive]}>
<Icon styles={styles.searchIcon} icon={searchIcon} />
<TextInput
style={styles.searchInput}
onChangeText={onChangeSearchText}
value={searchText}
onFocus={() => setSearchViewFocused(true)}
onBlur={() => setSearchViewFocused(false)}
autoCompleteType={"off"}
numberOfLines={1}
/>
{searchText !== "" && (
<Pressable style={styles.clearIcon} onPress={onClearSearchText}>
<Icon icon={cancelIcon} />
</Pressable>
)}
</View>
</View>
)
})
附件是
的图片预期。
VS
问题
当在聚焦状态下按下十字图标时,textInput 没有聚焦我想要实现的是搜索文本被清除并且输入保持聚焦。
注意:当输入未聚焦时,onPress 工作得很好
感谢任何帮助。谢谢!
PS:尝试了 TouchableOpacity 并且我还尝试将组件包装在 ScrollView 中以使用 keyboardShouldPersistTaps='handled',如 SO 答案之一所述,但没有成功。
您正在根据 TextInput 是否具有焦点来设置整个组件的焦点。由于清除按钮在文本输入之外,按下它会导致组件失去焦点。
一种解决方案是将 TextInput 实例存储在 ref 中。当按下清除按钮时,您可以重新聚焦文本输入。我在下面复制了您的组件并添加了一些新行,这些行已在注释中标记。
export const Component = (props): JSX.Element {
const { searchText, onChangeSearchText, onClearSearchText } = props
const textInputRef = useRef(null); // new
const [searchViewFocused, setSearchViewFocused] = useState<boolean>(false)
const searchIcon = searchViewFocused ? "searchActive" : "searchInactive"
const cancelIcon = searchViewFocused ? "cancelActive" : "cancelInactive"
const onClear = () => {
onClearSearchText();
textInputRef.current?.focus();
} // new
return (
<View style={styles.searchBoxContainer}>
<View style={[styles.searchBox, searchViewFocused && styles.searchBarActive]}>
<Icon styles={styles.searchIcon} icon={searchIcon} />
<TextInput
ref={textInputRef} // new
style={styles.searchInput}
onChangeText={onChangeSearchText}
value={searchText}
onFocus={() => setSearchViewFocused(true)}
onBlur={() => setSearchViewFocused(false)}
autoCompleteType={"off"}
numberOfLines={1}
/>
{searchText !== "" && (
<Pressable style={styles.clearIcon} onPress={onClear}> // calls new function
<Icon icon={cancelIcon} />
</Pressable>
)}
</View>
</View>
)
})
找到一个解决方法是将整个组件包装到 ScrollView 中并添加道具 keyboardShouldPersistTaps='handled'
之前,我将 Component
中的视图设为 ScrollView 并添加了 keyboardShouldPersistTaps='handled'
,但没有用
export const Component = (props): JSX.Element {
...
return (
<ScrollView contentContainerStyle={styles.searchBoxContainer}
keyboardShouldPersistTaps='handled'>
...
</ScrollView>
)
})
关键是将整个组件包裹在 ScrollView 中,
这是有效的方法:
<ScrollView keyboardShouldPersistTaps='handled'>
<Component {...props}/>
</ScrollView>
我猜这是一个愚蠢的错误,但值得指出!