I am trying to prevent re-render my child component <FyTable />
I have parent component called <TableCustomer />
this is parent component looks like
import {
columnDef_FilterCustomer,
columnType_FilterCustomer,
} from "./ColumnDef";
import { useDebounce } from "@uidotdev/usehooks";
const TableCustomer = (props) => {
const { resetRowSelection = false } = props;
const [filterData, setFilterData] = useState([]); //textfield filter values
const debounceFilter = useDebounce(filterData, 500); //debounce, to avoid calling useQuery for every keypress
const [tbData, setTbData] = useState({}); //useQuery result will be set
const handleSelectedRow = useCallback((tbCustomerSeletedRow) => {
console.log(tbCustomerSeletedRow) //print selected row from child component
}, [debounceFilter,columnDef_FilterCustomer,
tbData,columnType_FilterCustomer,resetRowSelection]);
const handleFilter = (event) => {
// logic...
setFilterData(arrayValue)
}
// calling useQuery debounceFilter as a parameter
const {
isSuccess: isSuccess_get_filterCustomer,
data: data_get_filterCustomer,
isError: isError_get_filterCustomer,
error: error_get_filterCustomer,
isPending: isPending_get_filterCustomer,
fetchStatus: fetchStatus_get_filterCustomer,
} = query_Get_FilterCustomer(debounceFilter);
useEffect(() => {
if (isSuccess_get_filterCustomer) {
setTbData(data_get_filterCustomer?.data);
}
if (isError_get_filterCustomer) {
console.log(error_get_filterCustomer);
}
}, [isSuccess_get_filterCustomer,data_get_filterCustomer,
isError_get_filterCustomer,error_get_filterCustomer]);
return (
<>
{/* Filter Fields */}
<TextField
variant="filled"
label="Customer No"
name="custNo"
onChange={(event) => handleFilter(event)}
/>
<TextField
variant="filled"
label="Customer Name"
name="custName"
onChange={(event) => handleFilter(event)}
/>
<TextField
variant="filled"
label="Phone No"
name="phoneNo"
onChange={(event) => handleFilter(event)}
/>
{/* Customer Table */}
<FyTable
columnDef={columnDef_FilterCustomer}
data={tbData}
columnDataType={columnType_FilterCustomer}
resetRowSelection={resetRowSelection}
handleSelectedRow={handleSelectedRow}
/>
</>
)}
export default TableCustomer
My child table component export with memo
export default React.memo(FyTable);
everything working fine, without an error, But When I type text on any filter TextFields, it’s totally lagging, each key press calling child components
I agree if parent components any changes on state values (here filterData
onChange on TextFields), this will re-render child component
To avoid re-render, I tried to use useCallback hooks and memoize the child component. still it re-render like a hell…
What am i missing?. please give me some explanation
2
Answers
thanks to @AbdullahCh, who mentioned in the comments about
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
I followed this react.dev/memoizedcomponent
In my ChildComponent, I compare the current props with prevProps. Then it works smoothly
so my child component will be looks like this
Write a
arePropsEqual
func and decide when to re-render the child component:-