在 useRef() 对象 React-Native 组件中出现奇怪的行为

Getting weird behavior in useRef() object React-Native component

我正在使用 OTP 自动填充功能。我正在使用 react-native-otp-textinput,它工作正常。我正在为 OTP 文本字段使用 useRef(),所以当我收到短信时,我将使用此 useRef(),并填写值。

问题陈述:

  1. 当我第一次 运行 应用程序时,我的 useRef() 表现良好,我可以自动用 userRef().current.setValue() 填充项目。
  2. 当我第二次或第三次运行这个应用程序时,我总是得到这个错误

TypeError: Cannot read property 'setValue' of null, js engine: hermes

我做的是捕捉,背后的原因是什么。所以我确实在我的功能中安慰了它。第一次发现,console.log(useRef().current)打印数据,但是到了第二次或第三次,就returnsnull。我很困惑,为什么会这样?

这是我的代码:

 const otpInputRef = useRef(null);

 const startReadSMSListerner = async () => {
   // Checking permission, else getting one
   const hasPermission = await ReadSms.requestReadSMSPermission();
   // If given permission, start listening, else, leave it
   if(hasPermission){
     ReadSms.startReadSMS((status, sms, error) => {
       if(status === 'success'){
         console.log(otpInputRef.current); // <-- Comes fine for the first time, but null when we test it in the second time
         otpInputRef?.current.setValue(sms); // <--- Here is the code which is working weird
       }
     });
   }
 }
 
 useEffect(() => {
  if(Platform.OS === 'android') startReadSMSListerner();

  return () => ReadSms.stopReadSMS();
 }, [otpInputRef]);

我对此完全感到困惑,尝试跟进:

编辑

这是我的 OTP TextInput 在 JSX 中的样子

            <OTPTextInput
              ref={otpInputRef}
              defaultValue=""
              inputCount={4}
              keyboardType="numeric"
              returnKeyType="done"
              textContentType="oneTimeCode" // for iOS Autofill enable
              containerStyle={{justifyContent: 'center', padding: width / 15}}
              textInputStyle={styles.textInputContainer}
              handleTextChange={(text) => onChangetText(text)}
            />

const 不应该用作ref的数据类型,它应该 let。原因是根据 React-Native 的生命周期:

View loads first, and useEffect updates afterwards, so const was just initialising ref value as null only. let enabled the ref useRef() value to update, and make the job easier

 // This does the magic
 let otpInputRef = useRef(null);

 const startReadSMSListerner = async () => {
   // Checking permission, else getting one
   const hasPermission = await ReadSms.requestReadSMSPermission();
   // If given permission, start listening, else, leave it
   if(hasPermission){
     ReadSms.startReadSMS((status, sms, error) => {
       if(status === 'success'){
         otpInputRef.current?.setValue(sms); // <--- Works now, since it gets updated in the useEffect() call
       }
     });
   }
 } 

 useEffect(() => {
  if(Platform.OS === 'android') startReadSMSListerner();

  return () => ReadSms.stopReadSMS();
 }, [otpInputRef]);