android - TextInput 在本机反应中不起作用我将它与堆栈导航一起使用
问题描述
所以我正在尝试制作一个 OTP 身份验证流程。我在 phoneInput 屏幕上输入,然后转到 OTP 验证屏幕。在 OTPVercification 上,我的 textInput 不起作用。
应用程序.js
import * as React from 'react'
import { Button, View, Text } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { AuthenticationScreen } from './screens/AuthenticationScreen'
import { HomeScreen } from './screens/HomeScreen'
import { InputOTPScreen } from './screens/InputOTPScreen'
function App() {
const LoginStack = createStackNavigator()
const RootStack = createStackNavigator()
function MainStackScreen() {
return (
<LoginStack.Navigator>
<LoginStack.Screen
name='Authentication'
component={AuthenticationScreen}
/>
<LoginStack.Screen name='InputOTP' component={InputOTPScreen} />
</LoginStack.Navigator>
)
}
return (
<NavigationContainer>
<RootStack.Navigator
mode='modal'
headerMode='none'
initialRouteName='Login'
>
<RootStack.Screen name='Login' component={MainStackScreen} />
<RootStack.Screen name='Home' component={HomeScreen} />
</RootStack.Navigator>
</NavigationContainer>
)
}
export default App
AuthenticationScreen.js
import React, { useState, useRef, useEffect } from 'react'
import { globalstyles } from '../styles/globalstyle'
import {
Button,
View,
Text,
StyleSheet,
KeyboardAvoidingView,
TextInput,
Keyboard,
Platform,
} from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler'
export function AuthenticationScreen({ navigation }) {
let textInput = useRef(null)
const [phoneNumber, setPhoneNumber] = useState('')
const [focusInput, setFocusInput] = useState(true)
const [valid, setValid] = useState(false)
const onChangePhone = (number) => {
setPhoneNumber(number)
var matchval = /^[0-9]+$/
if (number.length === 10 && number.match(matchval)) {
setValid(true)
} else {
setValid(false)
}
}
const onPressContinue = () => {
if (valid) {
navigation.navigate('InputOTP')
} else {
alert('Please enter a valid number')
}
}
const onChangeFocus = () => {
setFocusInput(true)
}
const onChangeBlur = () => {
setFocusInput(false)
}
useEffect(() => {
textInput.focus()
})
return (
<View style={globalstyles.container}>
<KeyboardAvoidingView
keyboardVerticalOffset={50}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={globalstyles.containerAvoidingView}
>
<Text style={globalstyles.textTitle}>
{'Please input your mobile number'}
</Text>
<View
style={[
globalstyles.containerInput,
{
borderBottomColor: focusInput ? '#244DB7' : '#ffffff',
},
]}
>
<View style={globalstyles.openDialogView}>
<Text style={{ fontSize: 16 }}>{'+91'}</Text>
</View>
<TextInput
ref={(input) => (textInput = input)}
style={globalstyles.phoneInputStyle}
placeholder='Phone number'
keyboardType='numeric'
value={phoneNumber}
onChangeText={onChangePhone}
secureTextEntry={false}
onFocus={onChangeFocus}
onBlur={onChangeBlur}
autoCompleteType='tel'
maxLength={10}
autoFocus={focusInput}
/>
</View>
<View style={globalstyles.viewBottom}>
<TouchableOpacity onPress={onPressContinue}>
<View
style={[
globalstyles.btnContinue,
{
backgroundColor: valid ? '#244DB7' : 'gray',
},
]}
>
<Text style={globalstyles.textContinue}>Continue</Text>
</View>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</View>
)
}
输入OTPScreen.js
import React, { useState, useRef, useEffect } from 'react'
import { globalstyles } from '../styles/globalstyle'
import {
Button,
View,
Text,
StyleSheet,
KeyboardAvoidingView,
TextInput,
Platform,
} from 'react-native'
import { ScrollView, TouchableOpacity } from 'react-native-gesture-handler'
import { useFocusEffect } from '@react-navigation/native'
export function InputOTPScreen({ navigation }) {
// TextInput refs to focus programmatically while entering OTP
const firstTextInputRef = useRef(null)
const secondTextInputRef = useRef(null)
const thirdTextInputRef = useRef(null)
const fourthTextInputRef = useRef(null)
/////////////////////////////////////
let otpInput = useRef('')
const lenghtInput = 4
const [otpVal, setOtpVal] = useState('')
const [focusInput, setFocusInput] = useState(true)
const onChangeOtp = (otp) => {
setOtpVal(otp)
console.log(otp)
if (otp.length === lenghtInput) {
navigation.navigate('Home')
}
}
useEffect(() => {
otpInput.focus()
}, [])
// useEffect(() => {
// navigation.addListener('focus', () => {
// Screen was focused
// Do something
// otpInput.focus()
// })
// }, [])
const textChangeFocus = () => {
otpInput.focus()
}
return (
<View style={styles.container}>
<KeyboardAvoidingView
keyboardVerticalOffset={50}
//behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={globalstyles.containerAvoidingView}
>
<Text style={styles.textTitle}>
{'Input your OTP code sent via SMS'}
</Text>
<TextInput
ref={(input) => (otpInput = input)}
onChangeText={onChangeOtp}
style={{ height: 0, width: 40 }}
maxLength={lenghtInput}
value={otpVal}
keyboardType='numeric'
/>
<View style={styles.containerInput}>
{Array(lenghtInput)
.fill('')
.map((data, index) => (
<View
key={index}
style={[
styles.cellView,
{
borderBottomColor:
index === otpVal.length ? '#FB6C6A' : '#234DB7',
},
]}
>
<Text
style={styles.cellText}
autofocus={true}
onPress={textChangeFocus}
>
{otpVal && otpVal.length > 0 ? otpVal[index] : ''}
</Text>
</View>
))}
</View>
</KeyboardAvoidingView>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
containerAvoidingView: {
flex: 1,
alignItems: 'center',
padding: 10,
},
textTitle: {
marginBottom: 50,
marginTop: 50,
fontSize: 16,
},
//////////////////
containerInput: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
fontSize: 16,
},
cellView: {
alignItems: 'center',
borderBottomWidth: 1.5,
fontSize: 16,
justifyContent: 'center',
margin: 5,
paddingVertical: 10,
width: 40,
},
cellText: {
textAlign: 'center',
fontSize: 16,
width: 40,
},
bottomView: {
flexDirection: 'row',
//flex: 1,
//justifyContent: 'flex-end',
marginBottom: 50,
marginTop: 20,
alignItems: 'center',
},
btnChangeNumber: {
width: 150,
height: 50,
borderRadius: 10,
alignItems: 'flex-start',
justifyContent: 'center',
},
textChange: {
color: '#234DB7',
alignItems: 'center',
fontSize: 16,
},
btnResend: {
width: 150,
height: 50,
borderRadius: 10,
alignItems: 'flex-end',
justifyContent: 'center',
},
textresend: {
alignItems: 'center',
fontSize: 16,
},
})
请帮助我理解我的代码错误。我可以在网页上输入,但在 OTP 屏幕上的 android TextInput 上不起作用。请帮我解决这个问题
解决方案
删除 useEffect 代码并从 cellView 样式更改样式:
cellView: {
alignItems: "center",
borderBottomWidth: 1.5,
fontSize: 16,
justifyContent: "center",
margin: 5,
paddingVertical: 10,
width: 40,
},
必须将宽度应用于 textInput 组件