首页 > 解决方案 > 调用 Linking Event Listener 后,Formik State 返回 OLD 而不是 RECENT 或 CURRENT 值

问题描述

我正在尝试在 REACT-NATIVE 中创建注册流程。流程是:填写表单 > 验证并提交表单 > 打开返回深层链接的 URL > 捕获深层链接 > 使用表单值和深层链接参数注册用户

问题是当监听器被调用时,我尝试在其中使用 formik 表单值,它返回 Formik 的初始值,而不是更新的 CURRENT 值。

const formik = useFormik({
    initialValues: {
      username: '',
      email: '',
      password: ''
    },
    onSubmit: (values) => {
      Linking.openURL(URL);
    },
    validationSchema: getValidation(), // Yup.object
  });

useEffect(() => {
    Linking.addEventListener('url', handleOpenUrl);
    return () => {
      Linking.removeListener('url', handleOpenUrl);
    };
  }, []);

const handleOpenUrl = (event) => {
    var code = event.url.split('//')[1].split('/')[1];
  
    if (code !== 'error) {
      console.log(code , formik.values); // returns initialValue
      // onRegister(formik.values, code )
    }
  };

我调用 formik.handleSubmit() 来验证数据并调用 onSubmit

标签: javascriptreact-nativedeep-linkingformik

解决方案


对于遇到相同或类似问题的任何人,这就是它发生的原因以及我为解决它所做的工作。

问题/原因:

事件监听器只会在初始渲染时知道组件的状态。因为当状态改变时事件监听器不会更新,所以他们不会意识到发生的改变。这是 React 的事件监听器的问题,不仅仅是在 useFormik 中。

解决方案:

useRef钩子,它可以访问实时状态值

代码:

const formik = useFormik({
  initialValues: {
    username: '',
    email: '',
  }
  onSubmit: (values) => {
    Linking.openURL(URL_TO_OPEN);
  },
  validationScheme: someValidationScheme(), // Yup.object
});

// just like other hook, you need to put an initial value, use the same object used in useFormik
const formValueRef = useRef(initialValues);

// useRef.current - stores the CURRENT value you passed, and can be accessed anytime
const setFormValues = (values) => {
  formValueRef.current = values;
  formik.setValues(values);
};

useEffect(() => {
  Linking.addEventListener('url', handleOpenUrl);
  return () => {
    Linking.removeListener('url', handleOpenUrl);
  };
}, []);


const handleOpenUrl = (event) => {
  var code = event.url.split('//');

  if (code !== 'error) {
    //this NOW RETURNS the CURRENT VALUE of formik that is passed to formValueRef.current
    console.log(code, formValueRef.current.username, formValueRef.current.email); 
  }
}

推荐阅读