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

React Hook Form and persistent data on page reload

我正在使用 React Hook Form v7,我正在尝试使我的数据表单在页面重新加载时持久化。我阅读了官方 RHF documentation which suggests to use little state machine 并尝试实施它但没有成功。有更好的方法吗?然而...

我在使用它时遇到的第一个问题是,我的数据是一个复杂的对象,所以 updateAction 应该没那么容易。

第二个问题是我不知道何时以及如何触发updateAction来保存数据。我应该在输入模糊时触发它吗?输入变化时?

这是我的测试代码:

状态本身不会在页面重新加载时保留任何数据。
您需要将状态数据添加到本地存储。
然后将其加载回 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>
  )
}

如果坚持使用 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>
   )
}