GithubHelp home page GithubHelp logo

tiaanduplessis / react-hook-form-persist Goto Github PK

View Code? Open in Web Editor NEW
146.0 5.0 23.0 517 KB

Persist and populate react-hook-form form using storage of your choice

License: MIT License

TypeScript 100.00%
react-hook-form react-hook-forms persistent persistent-storage

react-hook-form-persist's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-hook-form-persist's Issues

`include` option is missing

The readme shows the following example

useFormPersist('form', {watch, setValue, include: ['email'] });

This option doesn't actually exist

I think it makes sense to add this option because most of the time you want to persist only 1 or 2 fields and not the whole form

Add something like include as well as ignore to persist certain form data

Is it possible to add something like include as well as ignore to persist certain form data?

Reason

  • Currently, the storage will still store the form data being ignored, as this package performs ignore after loading the data. This means that you can't prevent it from storing sensitive data, like a password field.
  • There is also a small performance and storage overhead watching unnecessary fields, albeit a negligible one.

Proposal

Supply include into watch (I've renamed ignore to exclude to align with the change):

export default (
  name,
  watch,
  setValue,
  { include, exclude, storage = window.sessionStorage } = {}
) => {
  const values = watch(include);

  useEffect(() => {
    const storageItem = storage.getItem(name);

    if (storageItem) {
      Object.entries(JSON.parse(storageItem)).forEach(([key, value]) => {
        if (!exclude?.includes(key)) {
          setValue(key, value);
        }
      });
    }
  }, [name]);

  useEffect(() => storage.setItem(name, JSON.stringify(values)));

  return { clear: () => storage.removeItem(name) };
};

Example usage:

// Persist all form fields
useFormPersist('form', watch, setValue);

// Persist all form fields except password
useFormPersist('form', watch, setValue, { exclude: ['password'] });

// Persist only the email field
useFormPersist('form', watch, setValue, { include: ['email'] });

exclude array value

Thank you for this useful lib, anw, I tried to passing exclude parameter for array field, so I have array field

setValue(`attributes[${index}].value`, theDate);

but this value not excluding from storage, do you have some suggestions?

useFormPersist causes the component to rerender on every field change

I'm not sure if this is fixable (but I hope it is). After setting up useFormPersist using the repro steps below, my page where useForm sits gets rerendered on every field change:

import useFormPersist from 'react-hook-form-persist'
const { setValue, watch } = form;

useFormPersist("form-storage", {
  watch, 
  setValue,
  storage: window.localStorage
});  

By commenting out the useFormPersist command above the problem is resolved but obviously the functionality is gone.

Motivation: Measured by Chrome DevTools / Performance tab, there is a 4-fold performance degradation with this command turned on (moving from 100ms to 400-500ms on my test case).

Suggestion: I think that if possible, the form should be persisted without causing the current element to rerender.

Calling conditionally?

I was looking at incorporating into an existing FormWizard component that uses RHF and is used in many places across our application. I’ve added a persistKey prop (string) that, when present, would just be used to enable form persist within that instance of the wizard. Like this:

if (persistKey && typeof persistKey === 'string') {
	useFormPersist(persistKey, {
		setValue,
		watch,
	});
}

However, it’s not recommended to conditionally apply hooks in a component, so what would be the recommended process here?

I was considering forking the project and adding something like this to the two useEffect blocks:

if (!name) return

Thoughts?

Bug: DOMException / security in cross-origin private browsing mode situations

Hi,

there is an issue with a specific security condition where this hook can potentially break a whole web application, also production deploys, just by using it in the intended way.

If you integrate a web app inside of an <iframe> but this <iframe> is not served from the same domain, we have a typical "vertical" / "whitelabel" / "intranet integration" / "extranet integration" use-case.

This standard use case can potentially break a whole application and render a white-screen in production when the user is visiting that site in private mode. In this condition, browsers like Chrome and Firefox activate specific security rules that cause a DOMException to happen, only if you just try to read window.sessionStorage / window.localStorage in your code:

This is happening here:
https://github.com/tiaanduplessis/react-hook-form-persist/blob/master/src/index.js#L16

And causes:

Bildschirmfoto 2021-11-17 um 15 30 19

...based on production transpiled and minified code from this lib:
react-hook-form-persist.js":function(e,t,n){var r=n("../../node_modules/react/index.js");e.exports=function(e,t,n){var a=t.watch,o=t.setValue,i=void 0===n?{}:n,s=i.storage,l=void 0===s?window.sessionStorage:s,

There are two ways to fix this:

  • you can wrap every use of the hook in try/catch
  • we can do that in the lib and provide a mock storage implementation, backed by a global variable object to persist data (more or less like sessionStorage, just that it wouldn't survive hard reloads, which is probably better than breaking code completely and at least gives a working app in most cases; just needs to be documented well)

I have that in code already and can PR it.

Are you aware of this thing and would you accept a PR?

Doesn't seem to work on refresh

I see the data in localStorage, however when I hit refresh, the data is there then it gets cleared before it can get loaded into the form.

useFormPersist(
    'form',
    { watch, setValue },
    {
      storage: window.localStorage,
    }
  )

SessionStorage works but can't figure out whats wrong with localStorage.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.