Improve useLiveify a bit

This commit is contained in:
Donkie
2024-08-07 12:19:25 +02:00
parent 3bd93cb0af
commit 736e59d1eb
2 changed files with 13 additions and 16 deletions

View File

@@ -1,7 +1,7 @@
import { LiveEvent } from "@refinedev/core"; import { LiveEvent } from "@refinedev/core";
import liveProvider from "./liveProvider"; import liveProvider from "./liveProvider";
import { getAPIURL } from "../utils/url"; import { getAPIURL } from "../utils/url";
import { useEffect, useMemo, useState } from "react"; import { useEffect, useState } from "react";
const liveProviderInstance = liveProvider(getAPIURL()); const liveProviderInstance = liveProvider(getAPIURL());
@@ -16,7 +16,6 @@ export function useLiveify<Data extends { id: number }>(
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
transformPayload: (payload: any) => Data transformPayload: (payload: any) => Data
) { ) {
// TODO: The hooks in this function is quite janky, and should be refactored to be more efficient
// New state that holds the dataSource with updated values from the live provider // New state that holds the dataSource with updated values from the live provider
const [updatedDataSource, setUpdatedDataSource] = useState<Data[]>(dataSource); const [updatedDataSource, setUpdatedDataSource] = useState<Data[]>(dataSource);
@@ -25,20 +24,15 @@ export function useLiveify<Data extends { id: number }>(
setUpdatedDataSource(dataSource); setUpdatedDataSource(dataSource);
}, [dataSource]); }, [dataSource]);
// Create a constant reference to itemIds. This is to prevent the useEffect below from triggering extra times.
const itemIds = dataSource.map((item) => item.id);
const [prevItemIds, setPrevItemIds] = useState<number[]>(itemIds);
if (JSON.stringify(itemIds) !== JSON.stringify(prevItemIds)) {
setPrevItemIds(itemIds);
}
// Subscribe to changes for all items in the dataSource // Subscribe to changes for all items in the dataSource
useEffect(() => { useEffect(() => {
const itemIds = dataSource.map((item) => item.id);
const subscription = liveProviderInstance?.subscribe({ const subscription = liveProviderInstance?.subscribe({
channel: `${resource}-list`, channel: `${resource}-list`,
params: { params: {
resource: resource, resource: resource,
ids: prevItemIds, ids: itemIds,
subscriptionType: "useList", subscriptionType: "useList",
}, },
types: ["update"], types: ["update"],
@@ -57,7 +51,7 @@ export function useLiveify<Data extends { id: number }>(
liveProviderInstance?.unsubscribe(subscription); liveProviderInstance?.unsubscribe(subscription);
} }
}; };
}, [resource, prevItemIds, transformPayload]); }, [resource, dataSource, transformPayload]);
return updatedDataSource; return updatedDataSource;
} }

View File

@@ -18,7 +18,7 @@ import { useLiveify } from "../../components/liveify";
import { removeUndefined } from "../../utils/filtering"; import { removeUndefined } from "../../utils/filtering";
import { EntityType, useGetFields } from "../../utils/queryFields"; import { EntityType, useGetFields } from "../../utils/queryFields";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { useMemo, useState } from "react"; import { useCallback, useMemo, useState } from "react";
dayjs.extend(utc); dayjs.extend(utc);
@@ -78,11 +78,14 @@ export const VendorList: React.FC<IResourceComponentsProps> = () => {
useStoreInitialState(namespace, tableState); useStoreInitialState(namespace, tableState);
// Collapse the dataSource to a mutable list // Collapse the dataSource to a mutable list
() => (tableProps.dataSource || []).map((record) => ({ ...record })), const queryDataSource: IVendor[] = useMemo(() => {
[tableProps.dataSource] return (tableProps.dataSource || []).map((record) => ({ ...record }));
const queryDataSource: IVendor[] = useMemo( }, [tableProps.dataSource]);
const dataSource = useLiveify(
"vendor",
queryDataSource,
useCallback((record: IVendor) => record, [])
); );
const dataSource = useLiveify("vendor", queryDataSource, (record: IVendor) => record);
if (tableProps.pagination) { if (tableProps.pagination) {
tableProps.pagination.showSizeChanger = true; tableProps.pagination.showSizeChanger = true;