My intention is to create a custom input element that avoids re-rendering whenever the input value changes, but at the same time notifies the parent if the input changes.
Input component:
import { useRef, useEffect, ChangeEvent } from "react";
type props = {
changeFunction?: (e: ChangeEvent<HTMLInputElement>) => void;
};
function TestInput({ changeFunction }: props) {
let inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
console.log("Input render");
});
function change(e: ChangeEvent<HTMLInputElement>) {
console.log("Input change", e.target.value);
if (inputRef.current) inputRef.current.value = e.target.value;
if (changeFunction) changeFunction(e);
}
return (
<input
ref={inputRef}
type="search"
id="test"
name="test"
autoComplete="off"
onChange={change}
/>
);
}
export default TestInput;
Parent component:
import { useCallback, useState, ChangeEvent } from "react";
import TestInput from "./Test";
function TestParent() {
let [value, setValue] = useState("");
let change = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setValue(e.target.value),
[]
);
return (
<div>
<p>Value: {value}</p>
<TestInput changeFunction={change} />
</div>
);
}
export default TestParent;
Despite using useCallback
the input component re-renders every time. If we exclude the changeFunction
prop this doesn’t happen. What could be the solution?