I have a component in React that essentially autosaves form input 3 seconds after the user's last keystroke. There are possibly dozens of these components rendered on my webpage at a time.
I have tried using debounce from Lodash, but that did not seem to work (or I implemented it poorly). Instead, I am using a function that compares a local variable against a global variable to determine the most recent function call.
Curiously, this code seems to work in JSFiddle. However, it does not work on my Desktop.
Specifically, globalEditIndex
seems to retain its older values even after the delay. As a result, if a user makes 5 keystrokes, the console.log
statement runs 5 times instead of 1.
Could someone please help me figure out why?
import React, {useRef, useState} from "react";
import {connect} from "react-redux";
import {func1, func2} from "../actions";
// A component with some JSX form elements. This component shows up dozens of times on a single page
const MyComponent = (props) => {
// Used to store the form's state for Redux
const [formState, setFormState] = useState({});
// Global variable that keeps track of number of keystrokes
let globalEditIndex = 0;
// This function is called whenever a form input is changed (onchange)
const editHandler = (e) => {
setFormState({
...formState,
e.target.name: e.target.value,
});
autosaveHandler();
}
const autosaveHandler = () => {
globalEditIndex++;
let localEditIndex = globalEditIndex;
setTimeout(() => {
// Ideally, subsequent function calls increment globalEditIndex,
// causing earlier function calls to evaluate this expression as false.
if (localEditIndex === globalEditIndex) {
console.log("After save: " +globalEditIndex);
globalEditIndex = 0;
}
}, 3000);
}
return(
// JSX code here
)
}
const mapStateToProps = (state) => ({
prop1: state.prop1,
prop2: state.prop2
});
export default connect(
mapStateToProps, { func1, func2 }
)(MyComponent);