首页 > 解决方案 > 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 上不起作用。请帮我解决这个问题

标签: androidreact-nativereact-navigation

解决方案


删除 useEffect 代码并从 cellView 样式更改样式:

cellView: {
    alignItems: "center",
    borderBottomWidth: 1.5,
    fontSize: 16,
    justifyContent: "center",
    margin: 5,
    paddingVertical: 10,
    width: 40,
},

必须将宽度应用于 textInput 组件


推荐阅读