-
Notifications
You must be signed in to change notification settings - Fork 1k
Cancel debounce function after FormField unmounts #6226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested. Cancelation works as expected. Nice job.
// long depending on how fast people type, and 200ms | ||
// would be an eye blink | ||
}, | ||
500, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wondering if this delay should be something the caller can configure? Especially since we don't know what kind of validation function might be called. There is a theme prop, but seems to have been abandoned...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree that this should be configurable. Since debounceDelay
is not being used currently I think we could change it from '300' to '500' and then use it here
const debouncedFn = debounce( | ||
() => { | ||
contextOnChange(event); | ||
// A half second (500ms) debounce can be a helpful |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this comment into base.js
, since that is where the value is being set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, done
// past it. 2 second (2000ms) might be too long depending | ||
// on how fast people type, and 200ms would be an eye blink | ||
}, 500); | ||
const debouncedFn = debounce( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we remove the Fn
suffix? It doesn't seem consistent with grommet's naming convention to include typing in variable names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -134,12 +134,14 @@ const Input = ({ component, disabled, invalid, name, onChange, ...rest }) => { | |||
); | |||
}; | |||
|
|||
const debounce = (func, wait) => { | |||
const debounce = (func, wait, fieldRef) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of making debounce() know about the ref, what about changing it to be a hook that will clear the timer automatically when the component is unmounted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I updated to use a hook in the latest commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A suggestion to tighten it up a bit:
const useDebounce = () => {
const [func, setFunc] = useState();
useEffect(() => {
const timer = setTimeout(() => func(), theme.global.debounceDelay);
return () => clearTimeout(timer);
}, [func]);
return setFunc;
};
...
const debounce = useDebounce();
...
if (contextOnChange) debounce(() => contextOnChange(event)));
untested, but perhaps you get the idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this in latest commit
}, 500); | ||
debouncedFn(); | ||
} | ||
if (contextOnChange) setDebounced(() => contextOnChange); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We seem to have lost the event argument to contextOnChange()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in latest commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking good, one simple comment
@@ -194,6 +183,19 @@ const FormField = forwardRef( | |||
const { formField: formFieldTheme } = theme; | |||
const { border: themeBorder } = formFieldTheme; | |||
|
|||
const useDebounce = () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this hook definition can be outside the component, above line 138.
What does this PR do?
Prevents the debounce function from executing if the FormField is unmounted.
Where should the reviewer start?
What testing has been done on this PR?
Tested with the following story and console log statements in the debounce function
How should this be manually tested?
Do Jest tests follow these best practices?
screen
is used for querying.userEvent
is used in place offireEvent
.asFragment()
is used for snapshot testing.Any background context you want to provide?
What are the relevant issues?
Closes #6130
Closes #6129
Screenshots (if appropriate)
Do the grommet docs need to be updated?
It might be good to add the
debounceDelay
theme prop to the FormField doc. I will create a PR for this.Should this PR be mentioned in the release notes?
Maybe
Is this change backwards compatible or is it a breaking change?
Backwards compatible