AutoFocus 下一个 TextInput onChangeText 崩溃
我想创建一个带有 6 个 TextInput 的 OTP 输入屏幕。我希望 TextInput 在输入前一个 TextInput 的值时自动聚焦到下一个 TextInput。
我按照 以下问题 中给出的解决方案进行操作。
但是我得到了一个异常
TypeError: null 不是对象(评估'textInputToFocus.current.focus')
所以基本上我的变量 textInputToFocus 在下面的代码中为空,我不确定为什么?
import React, { Component } from 'react';
import {
StyleSheet,
View,
Text,
} from 'react-native';
import { PasscodeTextInput } from '../Common/PasscodeTextInput';
import Button from 'react-native-button';
type Props = {}
export default class EnterOTP extends React.Component {
constructor(props) {
super(props)
this.state = {
passcode1: "",
passcode2: "",
passcode3: "",
passcode4: "",
passcode5: "",
passcode6: "",
}
this.passcode1 = React.createRef()
this.passcode2 = React.createRef()
this.passcode3 = React.createRef()
this.passcode4 = React.createRef()
this.passcode5 = React.createRef()
this.passcode6 = React.createRef()
this.inputNumber = this.inputNumber.bind(this);
}
onVerify = () => {
}
inputNumber(value, flag) {
const completeFlag = `passcode${flag}`
console.log(completeFlag);
console.log(value)
this.setState({[completeFlag]: value})
console.log(this.state);
flag = flag + 1
if (flag < 7 && value) {
const nextFlag = `passcode${flag}`
console.log(nextFlag);
const textInputToFocus = this[nextFlag]
console.log(textInputToFocus)
textInputToFocus.current.focus()
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.leftContainer}>
<Text style = {styles.firstText}>SMS Verification</Text>
<Text style = {styles.secondText}>We have sent an SMS with a verification code to +91 7777777777. Please enter it below.</Text>
</View>
<View style={[styles.passcodeContainer]}>
<PasscodeTextInput
autoFocus={true}
ref={this.passcode1}
onChangeText={number => this.inputNumber(number, 1)} />
<PasscodeTextInput
ref={this.passcode2}
onChangeText={number => this.inputNumber(number, 2)} />
<PasscodeTextInput
ref={this.passcode3}
onChangeText={number => this.inputNumber(number, 3)}/>
<PasscodeTextInput
ref={this.passcode4}
onChangeText={number => this.inputNumber(number, 4)} />
<PasscodeTextInput
ref={this.passcode5}
onChangeText={number => this.inputNumber(number, 5)}/>
<PasscodeTextInput
ref={this.passcode6}
onChangeText={number => this.inputNumber(number, 6)}/>
</View>
<View styles={[styles.centerEverything]}>
<Button
style={{ fontSize: 20, color: 'white' }}
containerStyle={styles.verifyButton}
onPress={() => this.onVerify()}
>
VERIFY
</Button>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
centerEverything: {
justifyContent: 'center',
alignItems: 'center',
flexDirection: 'row'
//backgroundColor: 'red'
},
container: {
flex: 1,
backgroundColor: 'white',
},
leftContainer: {
justifyContent: 'flex-start',
marginLeft: 20,
marginRight: 20,
marginTop: 50
},
passcodeContainer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
firstText: {
color:"#758D9E",
marginTop: 12,
fontSize: 30,
fontWeight: 'bold',
textAlign: 'left',
alignItems: 'flex-start',
marginLeft: 5,
marginRight: 5
},
secondText: {
color:"#758D9E",
marginTop: 18,
fontSize: 14,
marginLeft: 10,
marginRight: 10
},
verifyButton: {
//flex: 0.1,
justifyContent: 'center',
alignItems: 'center',
marginTop:30,
backgroundColor:'#F64658',
borderRadius:100,
borderWidth: 1,
borderColor: '#fff',
overflow: 'hidden',
height: 40,
//width: 300,
margin: 30
},
});
编辑:
我的 PasscodeTextInput 代码在
React.forwardRef
import React from 'react';
import {
View,
Text,
TextInput,
} from 'react-native';
const PasscodeTextInput = React.forwardRef(({ ref, autoFocus, onSubmitEditing, onChangeText, value}) => {
const { inputStyle, underlineStyle } = styles;
return(
<View>
<TextInput
ref={ref}
autoFocus={autoFocus}
onSubmitEditing={onSubmitEditing}
style={[inputStyle]}
maxLength={1}
keyboardType="numeric"
placeholderTextColor="#212121"
//secureTextEntry={true}
onChangeText={onChangeText}
value={value}
/>
<View style={underlineStyle} />
</View>
);
})
const styles = {
inputStyle: {
height: 80,
width: 30,
fontSize: 50,
color: '#212121',
fontSize: 20,
padding: 5,
margin: 5,
marginBottom: 0
},
underlineStyle: {
width: 30,
height: 4,
backgroundColor: '#202020',
marginLeft: 0
}
}
export { PasscodeTextInput };
之后
tl. dr.
将声明从
const PasscodeTextInput = ({ ref, autoFocus, onSubmitEditing, onChangeText, value}) =>; {
至:
const PasscodeTextInput = React.forwardRef(({autoFocus, onSubmitEditing, onChangeText, value}, ref) => {
不要忘记关闭 new 括号
说明:
ref
不是处理到组件的普通 prop。使用
ref
prop 时,React 内部将处理该 prop,尝试获取对组件实际实例的引用并将其设置在那里,并且 prop 永远不会到达您的实际组件代码。
由于您的
PasswordTextInput
组件被定义为函数,因此没有它的实例,因此您得到
null
。
您想要做的是将
ref
转发到
TextInput
组件。所以你明确表示要做出反应,请给您
ref
属性,以便您可以按照自己认为合适的方式处理它。在本例中,将其转发到
TextInput
组件。
For more info see https://reactjs.org/docs/forwarding-refs.html
也许您可以尝试在 JSX 中使用自定义属性。
属性运算符:
let autofocus= {'attribute ': 'value'}
渲染:
{...autofocus}
例如;
有状态组件:
......
<Input
isAutofocus={true}
tabindex="1"
........
/>
无状态组件:
import React from "react";
const Input = ({isAutofocus,tabindex .......}) => {
let autofocus = isAutofocus ? {'autoFocus' : " "} : ""
return (
<div className="form-group">
<label htmlFor={name}>{label}</label>
<input
{...autofocus}
tabIndex={tabindex}
............
/>
</div>
)
}
export default Input;