When writing a handler for several different inputs, I ran into the problem of re-rendering components in which there are child components. How can I remove the renderer?
Only components without children and components using useMemo are not rendered.
This is only part of the code. Here full code .
// handle changes from input
export const useInputHandler = ({ initValues }) => {
const [values, setValues] = useState(initValues || {});
const handlerChange = useCallback(
event => {
const target = event.target;
const name = target.name;
const value = target.value;
setValues({
...values,
[name]: value
});
},
[values]
);
return [values, handlerChange];
};
const App = () => {
const [clicksNum, setClicks] = useState(0);
const countClicks = useCallback(() => {
setClicks(c => c + 1);
}, []);
const [values, handleChange] = useInputHandler({
initValues: { simple: "", counter: "", empty: "" }
});
useEffect(() => {
console.log("VALUES: ", values);
}, [values, clicksNum]);
return (
<div style={{ display: "flex", flexDirection: "column", width: "30%" }}>
<Button onClick={countClicks} />
<Input onChange={handleChange} name="simple" value={values.simple}>
{<div>hello</div>}
</Input>
<Input onChange={handleChange} name="counter" value={values.counter}>
{clicksNum}
</Input>
<Input onChange={handleChange} name="empty" value={values.empty} />
</div>
);
};
I expect that the input components will not be re-render every time the button is clicked. In this case, only the second input (which name counter ) should be redrawn. Because it wraps up the value ( clicksNum ) of the state.
Your input re-renders, because it's children change.
{<div>Hello</div>}
is a different instance at every render.
If you replace this with something like this:
const hello = useMemo(() => <div>Hello</div>, []);
It will only create a new instance if any of the dependencies change. There are no dependencies, and your re-renders will be gone.
You can always prevent unwanted re-renders by memoizing any of your components, it will then re-render only if any of the dependencies change.
const memoizedInput = React.useMemo(
() => (
<Input onChange={handleChange} name="simple" value={values.simple}>
<Button onClick={countClicks} />
</Input>
),
[handleChange, countClicks, values.simple]
);
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.