Использование функции очистки useEffect для хранения значений форм в localStorage - PullRequest
1 голос
/ 07 апреля 2020

Я использую функцию очистки useEffect для хранения моих значений 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, являются текущими, а записанные (и сохраненные) в функции очистки являются устаревшими начальными значениями. Я думал, что функция будет обрабатываться лениво, поэтому переменная values будет иметь текущее значение. Как снимок в темноте, я также попытался использовать функцию получения значений формы. Но все равно старые устаревшие ценности. Что здесь происходит?

Ответы [ 2 ]

3 голосов
/ 07 апреля 2020

Существует два способа решения этой проблемы.

  1. передать значения в [] useEffect.
    React.useEffect(() => {
    // do stuff
    return function() {
      console.log(values)
      // store form data on unmount
      localStorage.setItem("formValues", JSON.stringify(values))
    };
  }, [values]);

Но таким образом, он будет сохранять при каждом изменении значений. Так что не подходит, если вы сохраняете только один раз, когда компонент отключен

Второй метод (useRef)
    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;
2 голосов
/ 07 апреля 2020

Если вы хотите очистить только при размонтировании компонента, это то, что вам нужно:

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))
    };
}, []);

Поскольку вы хотите просто очистить и обновить локальное хранилище при размонтировании компонента, вы должны передать пустой массив ([]) для использованияEffect. Если вы передадите пустой массив ([]), реквизиты и состояние внутри эффекта всегда будут иметь свои начальные значения (https://reactjs.org/docs/hooks-effect.html). Поскольку каждый эффект «принадлежит» определенному рендеру, в данном случае это первый рендер при монтировании компонента. Но может быть лучше обновлять localstorage при каждом изменении значений, и в этом случае вам нужно только передать [values] для использованияEffect.

...