我想用6 TextInput创建一个OTP输入屏幕。我希望TextInput在输入上一个TextInput的值时自动聚焦到下一个。
中给出的解决方案但是我遇到了一个异常TypeError: null is not an object(evaluating 'textInputToFocus.current.focus')
,所以基本上我的变量textInputToFocus在下面的代码中为null,我不确定为什么吗?
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
},
});
编辑: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 };
答案 0 :(得分:1)
tl。 博士,将声明更改为
const PasscodeTextInput = ({ ref, autoFocus, onSubmitEditing, onChangeText, value}) => {
收件人:
const PasscodeTextInput = React.forwardRef(({autoFocus, onSubmitEditing, onChangeText, value}, ref) => {
而且不要忘了关闭新括号
说明:
ref
不是正常的道具,它会根据您的组件进行处理。使用ref
道具时,react内部成员会处理该道具,尝试获取对组件实际实例的引用并将其设置在该实例中,而该道具永远不会到达您的实际组件代码。
由于您的PasswordTextInput
组件被定义为一个函数,因此没有实例化,因此您会得到null
。
您要执行的操作是将ref
向下转发到TextInput
组件。因此,您明确表示要做出反应,请给您ref
道具,以便您可以处理它,但认为适合您。在这种情况下,这会将其转发到TextInput
组件。
答案 1 :(得分:0)
也许您可以尝试在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;