reactjs React Hook Form和页面重新加载时的持久化数据

sqserrrh  于 2023-04-29  发布在  React
关注(0)|答案(3)|浏览(167)

我正在使用React Hook Form v7,我试图使我的数据表单在页面重新加载时持久化。我阅读了官方的RHF文档,其中建议使用little state machine,我试图实现它,但没有成功。有没有更好的办法?不过……
我使用它遇到的第一个问题是,我的数据是一个复杂的对象,所以updateAction应该不是那么容易。
第二个问题是我不知道何时以及如何触发updateAction来保存数据。我应该在输入模糊时触发它吗?在输入改变时?
下面是我的测试代码:

flseospp

flseospp1#

如果在localStorage中持久化对你有用,下面是我实现它的方法。
为持久化数据定义一个自定义钩子

export const usePersistForm = ({
  value,
  localStorageKey,
}) => {
  useEffect(() => {
    localStorage.setItem(localStorageKey, JSON.stringify(value));
  }, [value, localStorageKey]);

  return;
};

只需在表单组件中使用它

const FORM_DATA_KEY = "app_form_local_data";

export const AppForm = ({
  initialValues,
  handleFormSubmit,
}) => {
  // useCallback may not be needed, you can use a function
  // This was to improve performance since i was using modals
  const getSavedData = useCallback(() => {
    let data = localStorage.getItem(FORM_DATA_KEY);
    if (data) {
     // Parse it to a javaScript object
      try {
        data = JSON.parse(data);
      } catch (err) {
        console.log(err);
      }
      return data;
    }
    return initialValues;
  }, [initialValues]);

  const {
    handleSubmit,
    register,
    getValues,
    formState: { errors },
  } = useForm({ defaultValues: getSavedData() });
  const onSubmit: SubmitHandler = (data) => {
     // Clear from localStorage on submit
     // if this doesn’t work for you, you can use setTimeout
     // Better still you can clear on successful submission
    localStorage.removeItem(FORM_DATA_KEY);
    handleFormSubmit(data);
  };

  // getValues periodically retrieves the form data
  usePersistForm({ value: getValues(), localStorageKey: FORM_DATA_KEY });

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      ...
    </form>
   )
}
gstyhher

gstyhher2#

我已经遇到了这个问题,并通过创建一个名为useLocalStorage的自定义Hook来实现它。但是由于您使用的是React钩子形式,这使得代码有点复杂,而且不够干净!
我建议你简单地使用轻包react-hook-form-persist。你唯一需要做的工作就是在useForm hook之后添加useFormPersist hook。成交!

import { useForm } from "react-hook-form";
import useFormPersist from "react-hook-form-persist";

const yourComponent = () => {
  const {
    register,
    control,
    watch,
    setValue,
    handleSubmit,
    reset
  } = useForm({
    defaultValues: initialValues
  });

  useFormPersist("form-name", { watch, setValue });

  return (
    <TextField
      title='title'
      type="text"
      label='label'
      {...register("input-field-name")}
    />
    ...
  );
}
bnl4lu3b

bnl4lu3b3#

状态本身不会在页面重新加载时持久化任何数据。
您需要将状态数据添加到本地存储。
然后将其加载回componentDidMount上的状态(useEffect和空依赖数组)。

const Form = () => {
  const [formData, setFormData] = useState({})
  
  useEffect(() => {
    if(localStorage) {
      const formDataFromLocalStorage = localStorage.getItem('formData');
      if(formDataFromLocalStorage) {
        const formDataCopy = JSON.parse(formDataFromLocalStorage)
        setFormData({...formDataCopy})
      }
    }
  }, []);
  
  useEffect(() => {
    localStorage && localStorage.setItem("formData", JSON.stringify(formData))
  }, [formData]);
  
  const handleInputsChange = (e) => {
    setFormData({
      ...formData,
      [e.target.name]: e.target.value
    })
  }
  
  return (
    <div>
      <input 
        type="text" 
        name="firstName"
        placeholder='first name'
        onChange={e => handleInputsChange(e)}
        value={formData?.firstName}
      />
      <input 
        type="text" 
        name="lastName"
        placeholder='last name'
        onChange={e => handleInputsChange(e)}
        value={formData?.lastName}
      />
    </div>
  )
}

相关问题