Issue
I have some ionic segment buttons that essentially act as toggle switches. I'm trying to limit the rate at which the effects of the toggles can be switched/selected) and have tried Debounce & Throttle from both lodash and now underscores without success.
I'm currently using underscores and am still having the issue that the function is still being called freely despite the use of debounce.
Here's my code:
const SensorMeasurements: React.FC = () => {
//.....
const setOptionsHandler = (value: string, option: string, key: string) => {
if (value === "true") {
console.log("RESULT: True / " + value + " / " + option + " / " + key);
if (!settingsHandler(key)) {
setControlHandler(option, false); //toggle on
console.log("TOGGLE " + option + " ON!");
}
}
else { // false
console.log("RESULT: False / " + value + " / " + option + " / " + key);
if (settingsHandler(key)) {
setControlHandler(option, false); //toggle off
console.log("TOGGLE " + option + " OFF!");
}
}
}
const setOptionsHandlerThrottled = _.debounce(setOptionsHandler, 5000, true);
const setControlHandler = async (input: string, notify?: boolean) => {
let sysCommand = "";
switch (input) {
case "Reset":
sysCommand = "R";
break;
case "Test":
sysCommand = "T";
break;
case "Calibration":
sysCommand = "B";
break;
case "Logging":
sysCommand = "L";
break;
case "Trigger":
sysCommand = "H";
break;
case "Measuring":
sysCommand = "M";
break;
case "Unit":
sysCommand = "U";
break;
}
try {
const abControl = str2ab(sysCommand);
const dvControl = new DataView(abControl.buffer);
//console.log("CONTROL BUFFER", abControl);
await BleClient.initialize();
//if (isAndroid && (devices.deviceId ?? true)) {
// await BleClient.getDevices(devices.deviceId);
// await BleClient.disconnect(devices.deviceId);
//}
await BleClient.getDevices(devices.deviceId);
await BleClient.connect(devices.deviceId, (deviceId) => onDisconnect(deviceId));
await BleClient.write(devices.deviceId, SERV_SYSTEM_CONTROL, CHAR_OPERATIONAL_MODE, dvControl);
if (notify !== false) {
present(input + ' Command Sent.', 3000);
}
} catch (error) {
CatchError(error, "Disconnected");
}
}
const settingsHandler = (string: string) => {
return trueOrFalse(iTrueStates, string) as unknown as string;
}
const trueOrFalse = (array: string[], string: string) => {
//check if string is in the array - returns boolean
return array.includes(string);
}
return (
<IonSegment onIonChange={e => setOptionsHandlerThrottled(e.detail.value as string, "Trigger", "statusSensorHighTrigger")} className="lowercase" color="brand" value={settingsHandler("statusSensorHighTrigger")}>
<IonSegmentButton value="false">
<IonLabel>Low</IonLabel>
</IonSegmentButton>
<IonSegmentButton value="true">
<IonLabel>High</IonLabel>
</IonSegmentButton>
</IonSegment>
);
export default SensorMeasurements;
Why is setOptionsHandler
still being called when the IonSegmentButton changes regardless of the debounce timeout? Am I accidentally creating a new debounced function every time it's called?
Solution
Ultimately I ended up using AwesomeDebouncePromise as this worked best. In order to prevent the creation of a new Debounced function every rerender I wrapped the debounced function in a useMemo.
const setOptionsHandlerThrottled = useMemo( () => AwesomeDebouncePromise(setOptionsHandler, 3000), [iTrueStates] );
Answered By - Phill Healey
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.