React Native切换密码可见性时输入框内容跳至开头问题求助
React Native切换密码可见性时输入框内容跳至开头的修复方案
问题重现代码
const [password, setPassword] = useState('') const [passwordVisibility, setPasswordVisibility] = useState(false); <View style={styles.inputContainer}> <TextInput name="password" style={styles.inputField} autoCapitalize='none' value={password} autoCorrect={false} textContentType="newPassword" onChangeText={onChangeText} placeholder="Password" enablesReturnKeyAutomatically secureTextEntry={passwordVisibility} /> <Pressable onPress={() => {setPasswordVisibility(!passwordVisibility), console.log(password)}}> <Icon name={passwordVisibility == true ? 'eye' : 'eye-off' } size={23} color='purple' /> </Pressable> </View>
问题原因
当secureTextEntry属性值变化时,React Native会重新初始化TextInput组件,导致光标位置被强制重置到文本开头。
修复方案
通过保存并恢复光标位置解决该问题,具体实现步骤如下:
- 给TextInput添加ref引用,用于获取输入框实例
- 新增状态保存当前光标位置
- 在切换可见性前记录光标位置,切换后通过ref恢复位置
修改后的完整代码
import { useRef, useState } from 'react'; import { View, TextInput, Pressable } from 'react-native'; import Icon from 'react-native-vector-icons/Ionicons'; // 根据实际使用的图标库调整 const PasswordInput = () => { const [password, setPassword] = useState(''); const [passwordVisibility, setPasswordVisibility] = useState(false); const [cursorPosition, setCursorPosition] = useState(0); const passwordInputRef = useRef(null); const togglePasswordVisibility = () => { // 切换可见性前,先记录当前光标位置 if (passwordInputRef.current) { const currentSelection = passwordInputRef.current.getSelection(); setCursorPosition(currentSelection.start); } // 切换密码可见状态 setPasswordVisibility(prev => !prev); }; // 恢复光标位置的方法 const restoreCursor = () => { if (passwordInputRef.current) { passwordInputRef.current.setSelection(cursorPosition, cursorPosition); } }; return ( <View style={styles.inputContainer}> <TextInput ref={passwordInputRef} name="password" style={styles.inputField} autoCapitalize='none' value={password} autoCorrect={false} textContentType="newPassword" onChangeText={setPassword} // 替换为你原有的onChangeText逻辑 placeholder="Password" enablesReturnKeyAutomatically secureTextEntry={passwordVisibility} onFocus={restoreCursor} onLayout={restoreCursor} /> <Pressable onPress={togglePasswordVisibility}> <Icon name={passwordVisibility ? 'eye' : 'eye-off'} size={23} color='purple' /> </Pressable> </View> ); }; // 示例样式,可根据项目需求调整 const styles = { inputContainer: { flexDirection: 'row', alignItems: 'center', borderWidth: 1, borderColor: '#ccc', borderRadius: 8, paddingHorizontal: 12, paddingVertical: 8, }, inputField: { flex: 1, height: 40, }, }; export default PasswordInput;
关键说明
passwordInputRef:用来获取TextInput实例,调用getSelection()获取当前光标位置,调用setSelection()恢复光标位置togglePasswordVisibility:在切换可见性状态前,先捕获当前光标位置并保存到状态中restoreCursor:在输入框获得焦点或布局更新时,将光标恢复到之前保存的位置- 如果你的
onChangeText有自定义处理逻辑,直接替换代码中的setPassword即可
内容的提问来源于stack exchange,提问作者Coder Duck
相关产品推荐
相关产品推荐

