From f4c02d682b8e5656a7f7ac2afdcc46d2ab20d992 Mon Sep 17 00:00:00 2001 From: Ion Andrusciac Date: Wed, 11 Dec 2024 18:14:44 +0200 Subject: [PATCH] Converted `DebounceDecorator` to functional component --- .../DebounceDecorator/DebounceDecorator.js | 103 +++++++++--------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/internal/DebounceDecorator/DebounceDecorator.js b/internal/DebounceDecorator/DebounceDecorator.js index ddef0feac2..68d912cdbf 100644 --- a/internal/DebounceDecorator/DebounceDecorator.js +++ b/internal/DebounceDecorator/DebounceDecorator.js @@ -8,7 +8,7 @@ import hoc from '@enact/core/hoc'; import {Job} from '@enact/core/util'; import PropTypes from 'prop-types'; -import {Component} from 'react'; +import {useCallback, useEffect, useMemo} from 'react'; /** * Default config for {@link sandstone/internal/DebounceDecorator.DebounceDecorator}. @@ -60,66 +60,67 @@ const defaultConfig = { const DebounceDecorator = hoc(defaultConfig, (config, Wrapped) => { const {cancel, debounce, delay} = config; - return class extends Component { - static displayName = 'DebounceDecorator'; - - static propTypes = /** @lends sandstone/internal/DebounceDecorator.DebounceDecorator.prototype */ { - /** - * Handler for `onChange` events - * - * `'onChange'` can be changed to a different prop name by specifying the `debounce` - * config option. - * - * @see {@link sandstone/internal/DebounceDecorator.DebounceDecorator.defaultConfig#debounce} - * @name onChange - * @memberof sandstone/internal/DebounceDecorator.DebounceDecorator.prototype - * @type {Function} - * @public - */ - [debounce]: PropTypes.func - }; - - constructor (props) { - super(props); - this.job = new Job(this.emitEvent.bind(this), delay); - } - - componentWillUnmount () { - this.job.stop(); - } + const Debounce = (props) => { + let debounceProps = props; - emitEvent (ev) { - if (this.props[debounce]) { - this.props[debounce](ev); + const emitEvent = useCallback((ev) => { + if (props[debounce]) { + props[debounce](ev); } - } - - handleEvent = (ev) => { - this.job.start(ev); - }; + }, [props]); - handleCancel = (ev) => { - if (this.props[cancel]) { - this.props[cancel](ev); - } - this.job.stop(); - }; + const job = useMemo(() => new Job(emitEvent, delay), [emitEvent]); - render () { - let props = this.props; + useEffect(() => { + return () => { + // eslint-disable-next-line react-hooks/exhaustive-deps + job.stop(); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - if (debounce || cancel) { - props = {...props}; + const handleEvent = useCallback((ev) => { + job.start(ev); + }, [job]); - if (debounce) props[debounce] = this.handleEvent; - if (cancel) props[cancel] = this.handleCancel; + const handleCancel = useCallback((ev) => { + if (props[cancel]) { + props[cancel](ev); } + job.stop(); + }, [job, props]); - return ( - - ); + if (debounce || cancel) { + debounceProps = {...props}; + + if (debounce) debounceProps[debounce] = handleEvent; + if (cancel) debounceProps[cancel] = handleCancel; } + + return ( + + ); }; + + Debounce.displayName = 'DebounceDecorator'; + + Debounce.propTypes = {/** @lends sandstone/internal/DebounceDecorator.DebounceDecorator.prototype */ + /** + * Handler for `onChange` events + * + * `'onChange'` can be changed to a different prop name by specifying the `debounce` + * config option. + * + * @see {@link sandstone/internal/DebounceDecorator.DebounceDecorator.defaultConfig#debounce} + * @name onChange + * @memberof sandstone/internal/DebounceDecorator.DebounceDecorator.prototype + * @type {Function} + * @public + */ + [debounce]: PropTypes.func + }; + + return Debounce; }); export default DebounceDecorator;