How can I prevent re-rendering of child components in React? Everytime an ID saved in useState is updated at the parent level, the child gets rerendered and loses the selection.
Here is some sample code for the setup:
Parent component:
import React, { useState } from "react";
import ChildComponent from "./ChildComponent";
function ParentComponent() {
const [selectedProjectId, setSelectedProjectId] = useState("");
const handleProjectIdChange = (projectId) => {
setSelectedProjectId(projectId); //<--- this rerenders the ChildComponent which is NOT wanted
};
return (
<div>
<h1>Parent Component</h1>
<ChildComponent
selectedProjectId={selectedProjectId}
onProjectIdChange={handleProjectIdChange}
/>
<p>Selected project ID: {selectedProjectId}</p>
</div>
);
}
export default ParentComponent;
Child component:
import React, { useState } from "react";
function ChildComponent({ selectedProjectId, onProjectIdChange }) {
const [projectOptions, setProjectOptions] = useState([
{ id: "1", name: "Project 1" },
{ id: "2", name: "Project 2" },
{ id: "3", name: "Project 3" },
]);
const handleProjectChange = (event) => {
const projectId = event.target.value;
onProjectIdChange(projectId);
};
return (
<div>
<h2>Child Component</h2>
<select value={selectedProjectId} onChange={handleProjectChange}>
<option value="">Select a project</option>
{projectOptions.map((option) => (
<option key={option.id} value={option.id}>
{option.name}
</option>
))}
</select>
</div>
);
}
export default ChildComponent;
I tried react.memo, useCallbacks and other methods but nothing worked. I want to prevent useState to udpate the child components everytime the IDs get updated.
Since your child component's props are changing, the child component will re-render regardless, thus the solution is prevent the child component's props from changing when the Parent Component re-render.
1st, you can remove the prop selectedProjectId from the child component. The select-option doesn't need to be updated base on state change. Then add memo to the child component.
ChildComponent
function ChildComponent({ onProjectIdChange }) {
.....
return (
.....
<select onChange={handleProjectChange}>
....
export default React.memo(ChildComponent);
2nd, in the ParentComponent use useCallback to prevent handleProjectIdChange from changing on every re-render.
ParentComponent
....
const handleProjectIdChange = useCallback(
(projectId) => {
setSelectedProjectId(projectId);
},
[setSelectedProjectId]
);
....
return (
....
<ChildComponent
onProjectIdChange={handleProjectIdChange}
/>
....
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With