簡體   English   中英

AutoFocus next TextInput onChangeText 崩潰

[英]AutoFocus next TextInput onChangeText Crash

我想用 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之后的 PasscodeTextInput 代碼

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。 博士。 將聲明從
const PasscodeTextInput = ({ ref, autoFocus, onSubmitEditing, onChangeText, value}) => {
至:
const PasscodeTextInput = React.forwardRef(({autoFocus, onSubmitEditing, onChangeText, value}, ref) => {
並且不要忘記關閉新的括號

解釋:
ref不是處理到您的組件的普通道具。 當使用ref prop 時,react internals 將處理該 prop,嘗試獲取對組件實際實例的引用並將其設置在那里,並且 prop 永遠不會到達您的實際組件代碼。
由於您的PasswordTextInput組件被定義為 function,因此沒有它的實例,因此您得到null

您要做的是將ref轉發到TextInput組件。 所以你明確地說要做出反應,請給你ref道具,這樣你就可以處理它,但是你認為它適合你。 在這種情況下,它會將其轉發到TextInput組件。

有關更多信息,請參閱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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM