diff --git a/client/src/pages/filaments/list.tsx b/client/src/pages/filaments/list.tsx index 3bd9bf0..6cf0ee8 100644 --- a/client/src/pages/filaments/list.tsx +++ b/client/src/pages/filaments/list.tsx @@ -65,23 +65,26 @@ export const FilamentList: React.FC = () => { useStoreInitialState("filamentList", { sorters, filters }); // Collapse the dataSource to a mutable list and add a filament_name field - const dataSource: IFilamentCollapsed[] = (tableProps.dataSource ?? []).map( - (element) => { - let vendor_name: string | null; - if (element.vendor) { - vendor_name = element.vendor.name; - } else { - vendor_name = null; - } - return { ...element, vendor_name }; - } + const dataSource: IFilamentCollapsed[] = React.useMemo( + () => + (tableProps.dataSource ?? []).map((element) => { + let vendor_name: string | null; + if (element.vendor) { + vendor_name = element.vendor.name; + } else { + vendor_name = null; + } + return { ...element, vendor_name }; + }), + [tableProps.dataSource] ); - // Filter dataSource by the filters - const filteredDataSource = dataSource.filter(genericFilterer(typedFilters)); - - // Sort dataSource by the sorters - filteredDataSource.sort(genericSorter(typedSorters)); + // Filter and sort the dataSource + const filteredDataSource = React.useMemo(() => { + const filtered = dataSource.filter(genericFilterer(typedFilters)); + filtered.sort(genericSorter(typedSorters)); + return filtered; + }, [dataSource, typedFilters, typedSorters]); return ( = () => { useStoreInitialState("spoolList", { sorters, filters }); // Collapse the dataSource to a mutable list and add a filament_name field - const dataSource: ISpoolCollapsed[] = (tableProps.dataSource ?? []).map( - (element) => { - let filament_name: string; - if (element.filament.vendor && "name" in element.filament.vendor) { - filament_name = `${element.filament.vendor.name} - ${element.filament.name}`; - } else { - filament_name = element.filament.name ?? element.filament.id.toString(); - } - return { ...element, filament_name }; - } + const dataSource: ISpoolCollapsed[] = React.useMemo( + () => + (tableProps.dataSource ?? []).map((element) => { + let filament_name: string; + if (element.filament.vendor && "name" in element.filament.vendor) { + filament_name = `${element.filament.vendor.name} - ${element.filament.name}`; + } else { + filament_name = + element.filament.name ?? element.filament.id.toString(); + } + return { ...element, filament_name }; + }), + [tableProps.dataSource] ); - // Filter dataSource by the filters - const filteredDataSource = dataSource.filter(genericFilterer(typedFilters)); - - // Sort dataSource by the sorters - filteredDataSource.sort(genericSorter(typedSorters)); + // Filter and sort the dataSource + const filteredDataSource = React.useMemo(() => { + const filtered = dataSource.filter(genericFilterer(typedFilters)); + filtered.sort(genericSorter(typedSorters)); + return filtered; + }, [dataSource, typedFilters, typedSorters]); return ( = () => { // Store state in local storage useStoreInitialState("vendorList", { sorters, filters }); - // Copy dataSource to avoid mutating the original - const dataSource = [...(tableProps.dataSource || [])]; + // Collapse the dataSource to a mutable list + const dataSource: IVendor[] = React.useMemo( + () => (tableProps.dataSource || []).map((record) => ({ ...record })), + [tableProps.dataSource] + ); - // Filter dataSource by the filters - const filteredDataSource = dataSource.filter(genericFilterer(typedFilters)); - - // Sort dataSource by the sorters - filteredDataSource.sort(genericSorter(typedSorters)); + // Filter and sort the dataSource + const filteredDataSource = React.useMemo(() => { + const filtered = dataSource.filter(genericFilterer(typedFilters)); + filtered.sort(genericSorter(typedSorters)); + return filtered; + }, [dataSource, typedFilters, typedSorters]); return ( { field: keyof Obj; @@ -67,32 +68,35 @@ export function genericFilterer(filters: TypedCrudFilter[]) { export function useListFiltersForField( dataSource: Obj[], field: Field): ColumnFilterItem[] { - const filters: ColumnFilterItem[] = []; - dataSource.forEach((element) => { - const value = element[field]; - if (typeof value === "string" && value !== "") { - // Make sure it's not already in the filters - if (filters.find((f) => f.value === value)) { - return; + return React.useMemo(() => { + console.log("useListFiltersForField"); + const filters: ColumnFilterItem[] = []; + dataSource.forEach((element) => { + const value = element[field]; + if (typeof value === "string" && value !== "") { + // Make sure it's not already in the filters + if (filters.find((f) => f.value === value)) { + return; + } + filters.push({ + text: value, + value: value, + }); } - filters.push({ - text: value, - value: value, - }); - } - }); - // Sort the filters - filters.sort((a, b) => { - if (typeof a.text !== "string" || typeof b.text !== "string") { - return 0; - } - return a.text.localeCompare(b.text); - }); - filters.push({ - text: "", - value: "", - }); - return filters; + }); + // Sort the filters + filters.sort((a, b) => { + if (typeof a.text !== "string" || typeof b.text !== "string") { + return 0; + } + return a.text.localeCompare(b.text); + }); + filters.push({ + text: "", + value: "", + }); + return filters; + }, [dataSource, field]); } /**