Skip to content

Commit 8b7d2b5

Browse files
committed
more enhancements
1 parent a9dc92e commit 8b7d2b5

5 files changed

Lines changed: 30 additions & 13 deletions

File tree

examples/src/pages/tests/table/props/data/lazy-load-grouped-example.page.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,6 @@ function Cmp() {
106106
const { dataArrayLength } = useDataSourceSelector((ctx) => {
107107
return {
108108
dataArrayLength: ctx.dataSourceState.dataArray.length,
109-
loading: ctx.dataSourceState.loading,
110109
};
111110
});
112111
(globalThis as any).dataArrayLength = dataArrayLength;

source/src/components/DataSource/publicHooks/useDataSourceMasterDetailSelector.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,21 @@ import { useCallback, useContext } from 'react';
33
import type { DataSourceMasterDetailContextValue } from '../types';
44

55
import {
6+
createComponentStore,
67
useComponentStoreSelector,
78
useComponentStoreSingleValue,
89
} from '../../../utils/ComponentStore';
910
import { getDataSourceMasterDetailStoreContext } from '../DataSourceMasterDetailContext';
1011
import { DataSourceMasterDetailStore } from '../DataSourceMasterDetailStore';
1112
import { InfiniteTableRowInfo } from '../../InfiniteTable';
1213

14+
/**
15+
* A stable no-op store used as a fallback so that hooks are called
16+
* unconditionally (Rules of Hooks) even when outside a detail context.
17+
*/
18+
const NOOP_STORE = createComponentStore<any>();
19+
const NOOP_SELECTOR = () => undefined;
20+
1321
/**
1422
* Returns the raw master-detail store (or undefined when outside a detail row).
1523
*
@@ -79,10 +87,15 @@ export function useDataSourceMasterDetailSelector<R extends object>(
7987
const StoreContext = getDataSourceMasterDetailStoreContext<any>();
8088
const store = useContext(StoreContext) as DataSourceMasterDetailStore<any>;
8189

82-
if (!store) {
83-
return undefined;
84-
}
85-
return useComponentStoreSelector(store, selector) ?? undefined;
90+
// Always call the hook to satisfy the Rules of Hooks.
91+
// When no store exists, use a no-op store + no-op selector so
92+
// useSyncExternalStore is still invoked unconditionally.
93+
const result = useComponentStoreSelector(
94+
store || NOOP_STORE,
95+
store ? selector : (NOOP_SELECTOR as unknown as typeof selector),
96+
);
97+
98+
return store ? result ?? undefined : undefined;
8699
}
87100

88101
export function useMasterRowInfo<T = any>():
@@ -91,11 +104,15 @@ export function useMasterRowInfo<T = any>():
91104
const StoreContext = getDataSourceMasterDetailStoreContext<any>();
92105
const store = useContext(StoreContext) as DataSourceMasterDetailStore<any>;
93106

94-
if (!store) {
95-
return undefined;
96-
}
97-
return useComponentStoreSingleValue(
98-
store,
99-
(ctx) => ctx.masterRowInfo as InfiniteTableRowInfo<T>,
107+
// Always call the hook to satisfy the Rules of Hooks.
108+
const masterRowInfoSelector = store
109+
? (ctx: any) => ctx.masterRowInfo as InfiniteTableRowInfo<T>
110+
: (NOOP_SELECTOR as unknown as (ctx: any) => InfiniteTableRowInfo<T>);
111+
112+
const result = useComponentStoreSingleValue(
113+
store || NOOP_STORE,
114+
masterRowInfoSelector,
100115
);
116+
117+
return store ? result : undefined;
101118
}

source/src/components/InfiniteTable/components/InfiniteTableHeader/InfiniteTableHeader.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ function InfiniteTableInternalHeaderFn<T>(
6767
string,
6868
InfiniteTableComputedColumn<T>
6969
>,
70-
computed: ctx.computed,
7170
getState: ctx.getState,
7271
headerOptions: ctx.state.headerOptions,
7372
headerRenderer: ctx.state.headerRenderer,

source/src/components/InfiniteTable/components/InfiniteTableRow/InfiniteTableDetailRow.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ function InfiniteTableDetailRowFn<T>(props: InfiniteTableDetailRowProps<T>) {
5353

5454
React.useLayoutEffect(() => {
5555
masterDetailStore.notify();
56+
// this value is different whenever masterRowInfo.id changes
57+
// so we're fine with this not triggering a notification
58+
// on all renders
5659
}, [masterDetailContextValue]);
5760

5861
return (

source/src/components/InfiniteTable/hooks/useCellRendering.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,6 @@ export function useCellRendering<T>(
7878
} = useInfiniteTableSelector((ctx) => {
7979
return {
8080
actions: ctx.actions,
81-
state: ctx.state,
8281
getState: ctx.getState,
8382
getComputed: ctx.getComputed,
8483
getDataSourceMasterContext: ctx.getDataSourceMasterContext,

0 commit comments

Comments
 (0)