Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获取useRef()对象反应本机组件中的奇怪行为_Javascript_React Native_React Hooks_Use Ref - Fatal编程技术网

Javascript 获取useRef()对象反应本机组件中的奇怪行为

Javascript 获取useRef()对象反应本机组件中的奇怪行为,javascript,react-native,react-hooks,use-ref,Javascript,React Native,React Hooks,Use Ref,我正在使用OTP自动填充功能。我正在使用,效果很好。我正在对OTP文本字段使用useRef(),因此当我收到短信时,我将使用此useRef(),并将其填入值中 问题陈述: 当我第一次运行应用程序时,我的useRef()表现良好,我可以用userRef().current.setValue()自动填充项目 当我第二次或第三次运行该应用程序时,总是会出现此错误 TypeError:无法读取null的属性“setValue”,js引擎:hermes 我所做的就是捕捉,这背后的原因是什么。所以我确实在我

我正在使用OTP自动填充功能。我正在使用,效果很好。我正在对OTP文本字段使用useRef(),因此当我收到短信时,我将使用此
useRef()
,并将其填入值中

问题陈述:

  • 当我第一次运行应用程序时,我的
    useRef()
    表现良好,我可以用
    userRef().current.setValue()
    自动填充项目
  • 当我第二次或第三次运行该应用程序时,总是会出现此错误
  • TypeError:无法读取null的属性“setValue”,js引擎:hermes

    我所做的就是捕捉,这背后的原因是什么。所以我确实在我的函数中对其进行了处理。我第一次发现,
    console.log(useRef().current)
    会打印数据,但当第二次或第三次打印时,它会返回null。我很困惑,为什么会这样

    这是我的密码:

     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]);
    
    const otpInputRef=useRef(null);
    const startReadSMSListerner=async()=>{
    //正在检查权限,否则将获得权限
    const hasPermission=wait ReadSms.requestreadsmpermission();
    //如果得到允许,开始听,否则就离开
    如果(已获得许可){
    ReadSms.startReadSMS((状态、sms、错误)=>{
    如果(状态==“成功”){
    console.log(otpInputRef.current);//ReadSms.stopReadSMS();
    },[otpInputRef]);
    
    我对此完全困惑,尝试跟进:

    编辑 下面是我的OTP TextInput在JSX中的外观

    onChangetText(text)}
    />
    

    常量
    不应用作
    参考
    的数据类型,它应
    。原因取决于React Native的生命周期:

    首先加载视图,然后更新useEffect,所以const只是将ref值初始化为null only。让我们启用ref useRef()值进行更新,使工作更轻松

    //这很神奇
    让otpInputRef=useRef(null);
    const startReadSMSListerner=async()=>{
    //正在检查权限,否则将获得权限
    const hasPermission=wait ReadSms.requestreadsmpermission();
    //如果得到允许,开始听,否则就离开
    如果(已获得许可){
    ReadSms.startReadSMS((状态、sms、错误)=>{
    如果(状态==“成功”){
    otpInputRef.current?.setValue(sms);//{
    如果(Platform.OS==='android')startReadSMSListerner();
    return()=>ReadSms.stopReadSMS();
    },[otpInputRef]);
    
    我从未使用过
    useRef
    setValue
    方法,在文档中找不到任何提及。你在哪里看到过它?@Konstantin
    setValue
    是一种OTP文本输入方法(见问题中的链接)这可能不会解决此特定问题,但通常在访问ref时,请执行
    ref.current?
    而不是
    ref?.current
    (ref本身始终是定义的,但
    current
    属性可能不是).Hm…也许应该是
    来代替,如果
    常量
    。这个组件能工作吗?:)很高兴它能工作!我从来没有机会仔细看看React Native,所以这对我来说是一个很好的机会:)我用过,而且我喜欢它在我的设备上轻松集成和运行。我会添加一个答案,可以随意升级或删除它如果需要,请编辑谢谢你的回答,我已经改进了答案。谢谢你的建议:)
     // 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]);