Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/25.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.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
Reactjs 使用useEffect清理函数在localStorage中存储表单值_Reactjs_Formik - Fatal编程技术网

Reactjs 使用useEffect清理函数在localStorage中存储表单值

Reactjs 使用useEffect清理函数在localStorage中存储表单值,reactjs,formik,Reactjs,Formik,我正在使用useffectcleanup函数将我的formik值存储在localStorage中。奇怪的是,存储的值是过时的初始值,而不是当前表单值。代码如下: console.log(values) React.useEffect(() => { // do stuff return function() { console.log(values) // store form data on unmount localStora

我正在使用
useffect
cleanup函数将我的formik值存储在localStorage中。奇怪的是,存储的值是过时的初始值,而不是当前表单值。代码如下:

  console.log(values)
  React.useEffect(() => {
    // do stuff
    return function() {
      console.log(values)
      // store form data on unmount
      localStorage.setItem("formValues", JSON.stringify(values))
    };
  }, []);

在useEffect函数外部记录的值是当前值,在cleanup函数中记录(并存储)的值是过时的初始值。我认为函数将被延迟计算,因此
变量将具有当前值。在黑暗中拍摄时,我还尝试对表单值使用getter函数。但仍然是陈旧的价值观。这里发生了什么?

有两种方法可以解决此问题

  • 在useEffect的[]内传递值 但通过这种方式,每次更改值时它都会保存 因此,如果在卸载组件时只保存一次,则不合适

  • 第二种方法(useRef)

  • 如果您只想在卸载组件时进行清理,这就是您想要的:

    const valuesRef = useRef(values);
    
    useEffect(() => {
        valuesRef.current = values;
    }, [values]);
    
    useEffect(() => {
        // do stuff
        return function() {
          console.log(valuesRef.current)
          // store form data on unmount
          localStorage.setItem("formValues", JSON.stringify(valuesRef.current))
        };
    }, []);
    
    因为您只需要在卸载组件时清理和更新localstorage,所以应该将空数组([])传递给useEffect。 如果传递一个空数组([]),效果中的道具和状态将始终具有其初始值()。这是因为每个效果“属于”一个特定的渲染,在这种情况下,它是安装组件时的第一个渲染。
    但最好在每次值更改时更新localstorage,在这种情况下,您只需将[values]传递给useEffect

    所以这是可行的,但为什么在应该延迟评估函数时需要ref?useEffect with sensivity list[]在组件装载时仅运行1次,这也意味着useEffect的返回函数将在组件卸载时运行1次。由于useEffect在组件生命周期中运行一次,所以它只捕获值的初始值。我编写了另一个useEffect,每次值更改时运行,并将值复制到ref。我理解的是,我不理解的是,为什么卸载时运行一次的cleanup函数会返回一个过时的值。我认为函数是惰性计算的,所以在卸载时,
    values
    变量不应该指向current values对象吗?如果传递一个空数组([]),效果中的道具和状态将始终具有其初始值。每个效果“属于”特定渲染。懒散地评估?“否”,这是因为每个效果“属于”一个特定的渲染,在这种情况下,它是安装组件()时的第一个渲染。所以这是可行的,但为什么在应该延迟评估函数时需要ref呢?
        const formikRef = React.useRef();
        formikRef.current = useFormik({
          initialValues: ...,
          onSubmit: ...,
          validationSchema: ...
        });
        React.useEffect(() => {
          // do stuff
          return () => {
            console.log(formikRef.current.values);
            // store form data on unmount
            localStorage.setItem(
              "formValues",
              JSON.stringify(formikRef.current.values)
            );
          };
        }, []);
    
      const formik = formikRef.current;
    
    const valuesRef = useRef(values);
    
    useEffect(() => {
        valuesRef.current = values;
    }, [values]);
    
    useEffect(() => {
        // do stuff
        return function() {
          console.log(valuesRef.current)
          // store form data on unmount
          localStorage.setItem("formValues", JSON.stringify(valuesRef.current))
        };
    }, []);