我正在尝试阻止重新渲染我的子组件
<FyTable />
我有一个名为
<TableCustomer />
的父组件
这是父组件的样子
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
我的子表组件使用
memo
导出
export default React.memo(FyTable);
一切正常,没有错误,但是当我在任何过滤器文本字段上键入文本时,它完全滞后,每个按键都会调用子组件
我同意如果父组件对状态值有任何更改(此处
filterData
TextFields 上的 onChange),这将重新渲染子组件
为了避免重新渲染,我尝试使用 useCallback 挂钩并记住子组件。它仍然像地狱一样重新渲染......
我错过了什么?请给我一些解释
感谢@AbdullahCh,他在评论中提到了
const MemoizedComponent = memo(SomeComponent, arePropsEqual?)
我遵循了这个react.dev/memoizedcomponent
在我的 ChildComponent 中,我将当前的 props 与 prevProps 进行比较。然后就可以顺利运行了
所以我的子组件将如下所示
const ChildComponent = (props) => {
//logic..
return(
<>
</>
)
}
function propsAreEqual(prevProps, nextProps){
console.log('🚀 Props are equal Triggered')
//console.log(prevProps)
//console.log(nextProps)
/**
* check prevProps and nextProps(current props) are equal
* if all prevProps and nextProps are totally equal then return 'true'. so IT WILL NOT RE-RENDER
* if prevProps and nextProps are not equal return 'false', then component will re-render
*/
let isSamePropsStatus = true
if(JSON.stringify(prevProps?.data) === JSON.stringify(nextProps?.data)) { isSamePropsStatus= true} else {isSamePropsStatus=false}
// compare rest of all props, based on your priority
return isSamePropsStatus
}
export default React.memo(ChildComponent, propsAreEqual); //wrap the component and props comparison function