Pretty new to React Hooks and I ran into this issue. I have a functional component that takes an input and sends it to the parent component when I hit the enter key (keycode = 13). The component looks something like this.
const SearchTermBar = (props) => {
const {resetStateSearchTerm, handlePowerToggleParent} = props;
const [inputTerm, handleInputChange] = useState('');
const inputRef = useRef();
useEffect(() => {
const keyPressEvent = (e) => {
if (e.keyCode === 13) {
resetStateSearchTerm(inputTerm);
handleInputChange('');
handlePowerToggleParent('search');
}
};
inputRef.current.addEventListener('keydown', keyPressEvent);
let parentInputRef = inputRef;
return () => {
console.log('remove event listener');
parentInputRef.current.removeEventListener('keydown', keyPressEvent);
}
}, [inputTerm, resetStateSearchTerm, handlePowerToggleParent]);
return (
<div className='SearchTermBar'>
<input
type='text'
placeholder='Enter search term here (Press return to confirm)'
className='SearchTermBar__Input'
value={inputTerm}
onChange={(e) => handleInputChange(e.target.value)}
ref={inputRef}
/>
</div>
);
The problem is that the event is registered and unregistered every time the inputTerm
or props
value changes. But I am not able to figure out the correct way to handle the event registration/removal (which should happen once ideally) I understand it is because of the dependency on the inputTerm
but I would like to know a better solution to this problem.
You already has the input ref, you don't really need a state:
const NOP = () => {};
const DEFAULT_INPUT = "";
function SearchTermBar(props) {
const { resetStateSearchTerm = NOP, handlePowerToggleParent = NOP } = props;
const inputRef = useRef();
useEffect(() => {
const keyPressEvent = (e) => {
if (e.keyCode === 13) {
resetStateSearchTerm(inputRef.current.value);
inputRef.current.value = DEFAULT_INPUT;
handlePowerToggleParent("search");
}
};
inputRef.current.addEventListener("keydown", keyPressEvent);
let parentInputRef = inputRef;
return () => {
console.log("remove event listener");
parentInputRef.current.removeEventListener("keydown", keyPressEvent);
};
}, [resetStateSearchTerm, handlePowerToggleParent]);
return (
<input
type="text"
placeholder="Enter search term here (Press return to confirm)"
style={{ width: "50%" }}
ref={inputRef}
/>
);
}
Either way, if you want to keep the state, its value should be duplicated into a ref to fix the closure in the useEffect
. It can be done by adding another useEffect
which will update the mentioned ref.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.