Skip to content

refactor(portal-framework-ui): refactor refineTable usage to align with @refinedev/react-table v4 API#538

Merged
pcfreak30 merged 6 commits intodevelopfrom
fix-ui-tables
Dec 8, 2025
Merged

refactor(portal-framework-ui): refactor refineTable usage to align with @refinedev/react-table v4 API#538
pcfreak30 merged 6 commits intodevelopfrom
fix-ui-tables

Conversation

@pcfreak30
Copy link
Copy Markdown
Member

@pcfreak30 pcfreak30 commented Dec 8, 2025

  • Updated imports and type references to use UseTableReturnType from @refinedev/react-table
  • Modified BaseTable and DataTable components to access refineCore properties
  • Updated RefineTableProvider to use refineCore for refs and context values
  • Adjusted Toolbar to access refineCore properties

Summary by CodeRabbit

  • Refactor
    • Standardized table internals around a single core-backed structure; table state and actions now surface via the core.
    • Toolbar and table components now source filters, sorters and query state consistently from the core, improving sync.
    • Provider now supplies the full refined table object while public DataTable export remains unchanged.
    • Breaking change: Integrations depending on prior table property shapes must update to the new core-backed access.

✏️ Tip: You can customize this high-level summary in your review settings.

…th @refinedev/react-table v4 API

- Updated imports and type references to use `UseTableReturnType` from `@refinedev/react-table`
- Modified `BaseTable` and `DataTable` components to access `refineCore` properties
- Updated `RefineTableProvider` to use `refineCore` for refs and context values
- Adjusted `Toolbar` to access `refineCore` properties
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Dec 8, 2025

⚠️ No Changeset found

Latest commit: a72ee2a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 8, 2025

Walkthrough

Retyped and narrowed refineTable usages to the UseTableReturnType shape and/or its refineCore subtree across data-table components; updated imports, runtime property access (filters, sorters, tableQuery, reactTable options), context/provider wiring, and minor cleanup in DataTable.

Changes

Cohort / File(s) Summary
Type & Context Definitions
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx, libs/portal-framework-ui/src/components/data-table/BaseTable.tsx
Replaced useTableReturnType with UseTableReturnType; narrowed refineTable types to UseTableReturnType or UseTableReturnType<...>["refineCore"]; updated context/provider prop and value shapes; adjusted setFilters/setSorters/types to reference refineCore.
Component Runtime Adjustments
libs/portal-framework-ui/src/components/data-table/DataTable.tsx, libs/portal-framework-ui/src/components/data-table/Toolbar.tsx
Runtime accesses switched to refineCore paths; DataTable now spreads refineTable.reactTable and reads reactTable.options; RefineTableProvider consumption/prop passing updated; Toolbar now sources refine-core properties directly (via useRefineTable).
Cleanup & Imports
libs/portal-framework-ui/src/components/data-table/DataTable.tsx
Removed unused useRef and instance counter; aliased getDefaultFilter import to refineGetDefaultFilter; updated imports to match UseTableReturnType usage and removed obsolete types.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Pay extra attention to:
    • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx — ref synchronization, deep-comparison logic, and memo/effect dependencies after switching to refineCore.
    • libs/portal-framework-ui/src/components/data-table/BaseTable.tsx — type narrowing and optional chaining correctness where external callers may pass older shapes.
    • libs/portal-framework-ui/src/components/data-table/DataTable.tsx & Toolbar.tsx — ensure reactTable spreads/options and filter/sorter reads/writes preserve behavior.

Possibly related PRs

Poem

🐇 I hopped through types and tidy cores,
I nudged the props and opened doors.
Filters, sorters, neat in line,
refineCore hummed — all working fine.
A carrot cheer for code that’s fine! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main refactoring effort: updating refineTable usage to align with @refinedev/react-table v4 API across multiple components and contexts.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-ui-tables

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c5a4b8 and a72ee2a.

📒 Files selected for processing (1)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4 hunks)
🔇 Additional comments (3)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (3)

36-36: Excellent resolution of the past stabilization issue!

The version-based memoization pattern correctly resolves the previous issue about refs not being used effectively. The implementation:

  1. Uses refs in context value (lines 103-109) — reads ref.current to access stabilized values
  2. Version state triggers updates (line 36, 96, 110) — correctly handles the fact that ref changes don't trigger re-renders
  3. Deep equality checks (lines 67, 77) — prevents false positives for filters/sorters
  4. Increments only on actual changes (line 95) — avoids unnecessary context updates

This is the proper pattern for ref-based stabilization with controlled memoization. The previous suggestion to depend on ref.current values wouldn't have worked because refs don't change identity when .current changes.

Also applies to: 52-98, 110-110


40-44: LGTM! Consistent refineCore access pattern.

The refs and tracking logic correctly access all properties through refineTable?.refineCore with proper optional chaining. This aligns well with the updated API structure.

Also applies to: 47-48, 66-66, 76-76, 89-89


8-10: Remove verification request—API compatibility confirmed.

The import of UseTableReturnType and the refineCore property access pattern (including setFilters, setSorters, tableQuery, filters, and sorters) are correct for @refinedev/react-table v6.0.1. The code properly implements the documented API structure where UseTableReturnType = Table<TData> & { refineCore: useTableReturnTypeCore }.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
libs/portal-framework-ui/src/components/data-table/Toolbar.tsx (1)

233-234: Consider using pre-extracted context values.

The RefineTableProvider context already extracts and exposes setFilters, setSorters, tableQuery, filters, and sorters at the top level of the context value. You could destructure these directly from useRefineTable() instead of re-navigating through refineTable?.refineCore:

-  const { refineTable } = useRefineTable<TData>();
+  const { setFilters, setSorters, tableQuery, filters, sorters } = useRefineTable<TData>();
   const { toolbarConfig: config, refineContext } = useTableConfig<TData>();
   const { getDefaultFilter, getDefaultOperator } = useFilterHelpers<TData>();
   // ...
-  const { setFilters, setSorters, tableQuery, filters, sorters } =
-    refineTable?.refineCore || {};

This approach is more consistent with the context's design and avoids redundant property access.

libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

99-109: Using ref.current as useMemo dependencies is an anti-pattern.

React cannot track mutations to ref.current, so changes to filtersRef.current or sortersRef.current won't trigger recomputation of this memoized value. The refineTable dependency does work, but the ref dependencies are effectively no-ops.

If the intent is to create a stable context value that updates only when filters/sorters actually change (after deep comparison), consider using state instead of refs, or restructure so the memo depends only on values React can track.

One approach:

  const value = useMemo(() => {
    return {
      refineTable: refineTableRef.current,
      setFilters: setFiltersRef.current,
      setSorters: setSortersRef.current,
      tableQuery: tableQueryRef.current,
      filters: filtersRef.current,
      sorters: sortersRef.current,
    };
-  }, [refineTable, filtersRef.current, sortersRef.current]);
+  }, [refineTable]);

The current approach may work due to refineTable triggering updates, but the ref deps create false confidence about reactivity. If more granular updates are needed, consider tracking filters/sorters in state variables that are updated within the useEffect.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a2131b and ecd8613.

📒 Files selected for processing (4)
  • libs/portal-framework-ui/src/components/data-table/BaseTable.tsx (5 hunks)
  • libs/portal-framework-ui/src/components/data-table/DataTable.tsx (3 hunks)
  • libs/portal-framework-ui/src/components/data-table/Toolbar.tsx (1 hunks)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
libs/portal-framework-ui/src/components/data-table/DataTable.tsx (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)
  • RefineTableProvider (34-116)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)
go/portal-dashboard/build/static/js/index-DzuUExDg.js (9)
  • refineTableRef (34157-34157)
  • setFiltersRef (34158-34158)
  • setSortersRef (34159-34159)
  • tableQueryRef (34160-34160)
  • sortersRef (34162-34162)
  • prevFiltersRef (34163-34163)
  • prevSortersRef (34164-34164)
  • newFilters (33669-33669)
  • deepEqual (34150-34150)
🔇 Additional comments (5)
libs/portal-framework-ui/src/components/data-table/DataTable.tsx (2)

92-98: LGTM! Correctly aligns with @refinedev/react-table v6 API structure.

The table composition now properly spreads refineTable.reactTable and attaches refineCore to options, which matches the v6 hook return type structure where useTable returns { reactTable, refineCore }.


114-114: LGTM!

Correctly passes the full refineTable object to RefineTableProvider, which aligns with the updated RefineTableProviderProps type expecting UseTableReturnType<TData, any>.

libs/portal-framework-ui/src/components/data-table/BaseTable.tsx (1)

38-41: LGTM!

The type narrowing to UseTableReturnType<TData, any>["refineCore"] correctly reflects that BaseTable receives only the refineCore portion of the table hook result.

libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (2)

13-20: LGTM!

The context value types are correctly updated to derive setFilters and setSorters types from UseTableReturnType<TData, any>["refineCore"], ensuring type consistency with the new API structure.


43-51: LGTM!

Refs are correctly initialized from refineTable?.refineCore?.* properties, aligning with the new type where refineTable is the full UseTableReturnType object.

…perty access

- Simplify RefineTable context by removing unnecessary dependencies
- Update property access in BaseTable to use tableQuery directly
- Remove redundant property extraction in Toolbar component
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
libs/portal-framework-ui/src/components/data-table/BaseTable.tsx (1)

256-265: Consistent with fix above — duplicate access pattern is correct.

🧹 Nitpick comments (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

100-109: Potential stale value on render when refineTable changes.

The useMemo depends on refineTable but reads from refs that are updated in useEffect. When refineTable changes:

  1. useMemo runs with the old ref values (refs not yet updated)
  2. useEffect runs and updates refs
  3. Next render would have correct values

This can cause one render cycle with stale context data. If intentional for stability, consider adding a comment. Otherwise, consider reading directly from refineTable?.refineCore in useMemo for immediate consistency:

  const value = useMemo(() => {
    return {
-     refineTable: refineTableRef.current,
-     setFilters: setFiltersRef.current,
-     setSorters: setSortersRef.current,
-     tableQuery: tableQueryRef.current,
-     filters: filtersRef.current,
-     sorters: sortersRef.current,
+     refineTable: refineTable,
+     setFilters: refineTable?.refineCore?.setFilters,
+     setSorters: refineTable?.refineCore?.setSorters,
+     tableQuery: refineTable?.refineCore?.tableQuery,
+     filters: refineTable?.refineCore?.filters,
+     sorters: refineTable?.refineCore?.sorters,
    };
  }, [refineTable]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ecd8613 and 0794f1b.

📒 Files selected for processing (3)
  • libs/portal-framework-ui/src/components/data-table/BaseTable.tsx (3 hunks)
  • libs/portal-framework-ui/src/components/data-table/Toolbar.tsx (2 hunks)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
libs/portal-framework-ui/src/components/data-table/Toolbar.tsx (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)
  • useRefineTable (118-126)
🔇 Additional comments (9)
libs/portal-framework-ui/src/components/data-table/Toolbar.tsx (2)

197-197: LGTM — Clean destructuring aligns with the updated context structure.

This change correctly retrieves the refine-core properties directly from the context, which now exposes them at the top level via RefineTableProvider. This is cleaner than the previous approach of accessing through optional chaining on the full refineTable object.


232-232: No substantive change.

libs/portal-framework-ui/src/components/data-table/BaseTable.tsx (3)

10-11: LGTM — Correct type import for v4 API.


38-41: LGTM — Type correctly narrowed to refineCore portion.

The prop type UseTableReturnType<TData, any>["refineCore"] indicates that BaseTable expects to receive only the refineCore portion of the table hook return value, not the full object. This is consistent with the property access patterns used below.


183-190: Past review issue addressed — property access now correct.

The property access props.refineTable?.tableQuery?.refetch correctly matches the narrowed type UseTableReturnType<TData, any>["refineCore"]. Since refineTable is already the refineCore object, the direct .tableQuery access is appropriate.

libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4)

9-20: LGTM — Types correctly structured for v4 API.

The context interface properly separates concerns:

  • refineTable holds the full UseTableReturnType for cases needing access to TanStack table features
  • setFilters/setSorters are typed to the refineCore sub-paths for direct access to refine-specific functions

42-51: LGTM — Refs correctly access refineCore properties.

Since refineTable is the full UseTableReturnType, accessing refineTable?.refineCore?.setFilters etc. is the correct path for v4 API.


54-97: LGTM — Effect correctly synchronizes refineCore values.

The deep comparison approach prevents context thrashing when filter/sorter arrays have the same content but different references.

Minor note: instanceId in the dependency array is unnecessary since it never changes after initialization, but this is harmless.


118-126: LGTM — Hook correctly returns typed context value.

…efineTableProvider

- Replaced ref.current pattern with direct object access (e.g., refineTable instead of refineTableRef.current)
- Updated context value derivation to use refineTable.refineCore properties directly
- Simplified dependency tracking in useMemo by removing ref.current dependencies
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

71-73: Remove unnecessary dependency and consider reset detection logic.

  1. Line 97: The instanceId dependency is unnecessary since it's created with an empty dependency array on line 39 and will never change.

  2. Lines 71-73 and 86-88: The reset detection logic has empty branches. If these are intentional placeholders for future functionality, consider adding a TODO comment. Otherwise, this code can be simplified by removing the reset detection checks.

Apply this diff to remove the unnecessary dependency:

-  }, [refineTable, instanceId]);
+  }, [refineTable]);

If reset detection is not needed, simplify the logic:

     if (filtersChanged) {
-      // Check for filter state reset
-      const oldFilters = prevFiltersRef.current || [];
-      if (oldFilters.length > 0 && newFilters.length === 0) {
-        // Filter state reset detected
-      }
-
       filtersRef.current = newFilters;
       prevFiltersRef.current = newFilters;
     }
     if (sortersChanged) {
-      // Check for sorter state reset
-      const oldSorters = prevSortersRef.current || [];
-      if (oldSorters.length > 0 && newSorters.length === 0) {
-        // Sorter state reset detected
-      }
-
       sortersRef.current = newSorters;
       prevSortersRef.current = newSorters;
     }

Also applies to: 86-88, 97-97

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0794f1b and e4175d5.

📒 Files selected for processing (1)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4 hunks)
🔇 Additional comments (2)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (2)

14-16: Type definitions are consistent with the new API structure.

The updated types correctly reference the refineCore nested structure. Using indexed access types (UseTableReturnType<TData, any>["refineCore"]["setFilters"]) ensures type safety when extracting these nested properties.


118-126: Hook implementation looks correct.

The useRefineTable hook follows the standard React context consumption pattern with proper error handling for missing provider context. The type casting ensures correct generic type propagation.

… for stable context values

- Removed filter/sorter state reset detection logic
- Updated context value to use ref.current values instead of direct properties
- Improved memoization by tracking individual ref.current dependencies
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

87-104: Anti-pattern: ref.current values in useMemo dependencies don't trigger re-computation.

React cannot track ref mutations. Using refineTableRef.current etc. in the dependency array doesn't cause useMemo to re-run when refs are updated—refs are mutable and don't trigger re-renders.

Problem sequence:

  1. refineTable prop changes → component re-renders
  2. useMemo runs with old ref.current values (effect hasn't run yet)
  3. useEffect runs and updates refs
  4. Context consumers receive stale data until next render

Consider using a version counter to force re-computation after the effect updates refs:

+  const [version, setVersion] = useState(0);
+
   useEffect(() => {
     // ... existing ref updates ...
+
+    // Signal that refs have been updated
+    setVersion((v) => v + 1);
   }, [refineTable]);
 
   const value = useMemo(() => {
     return {
       refineTable: refineTableRef.current,
       setFilters: setFiltersRef.current,
       setSorters: setSortersRef.current,
       tableQuery: tableQueryRef.current,
       filters: filtersRef.current,
       sorters: sortersRef.current,
     };
-  }, [
-    refineTableRef.current,
-    setFiltersRef.current,
-    setSortersRef.current,
-    tableQueryRef.current,
-    filtersRef.current,
-    sortersRef.current,
-  ]);
+  }, [version]);

This ensures useMemo recomputes after refs are updated, providing consumers with fresh data.

🧹 Nitpick comments (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

31-32: Remove unused instanceId generation.

generateInstanceId and instanceId are defined but never used anywhere in this component. This is dead code that should be removed.

-// Generate unique instance ID for tracking multiple provider instances
-const generateInstanceId = () => Math.random().toString(36).substr(2, 9);
-
 export function RefineTableProvider<TData extends BaseRecord>({
   children,
   refineTable,
 }: RefineTableProviderProps<TData>) {
-  // Create unique instance identifier
-  const instanceId = useMemo(() => generateInstanceId(), []);
-
   // Use refs to stabilize references and prevent contexts thrashing

Additionally, substr is deprecated—use substring if this code is kept for future use.

Also applies to: 39-39

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e4175d5 and cb86869.

📒 Files selected for processing (1)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (5 hunks)
🔇 Additional comments (4)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4)

9-20: Type updates correctly align with @refinedev/react-table v4 API.

The import change to UseTableReturnType and the updated type definitions properly reflect the v4 API structure where setFilters, setSorters, etc. are now nested under refineCore.


41-51: Ref initializations correctly updated for refineCore structure.

The refs are properly initialized to reference the refineCore sub-properties, aligning with the v4 API.


54-85: Effect logic correctly implements stabilization with deep comparison.

The effect properly updates refs only when actual data changes, using deep equality for filters/sorters. The refineCore path updates are correct.


113-121: Hook implementation is correct.

The useRefineTable hook follows the standard pattern with proper provider validation and type casting.

…to track ref updates

- Removed random instance ID generation
- Introduced useState for version tracking
- Updated useEffect to increment version when refs change
- Simplified context value dependencies to use version state
- Eliminated unnecessary useMemo dependencies
@pcfreak30
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (1)

36-97: Previous critical issue resolved, but version increments unconditionally.

The previous review's critical concern has been addressed—the context value (lines 88-96) now correctly uses the stabilized refs (e.g., setFiltersRef.current) and depends on version rather than refineTable object identity. This prevents context thrashing when refineTable reference changes but content is stable.

However, a new performance issue remains: setVersion((v) => v + 1) (line 84) executes on every effect run, even when none of the refs have actually changed. If refineTable object identity changes frequently (e.g., parent re-renders) but filters/sorters/etc. remain stable, consumers still re-render unnecessarily.

Consider tracking whether any ref was updated and only increment version when a change occurs:

  useEffect(() => {
+   let hasChanges = false;
+
    // Update function refs if they've changed
    if (refineTable?.refineCore?.setFilters !== setFiltersRef.current) {
      setFiltersRef.current = refineTable?.refineCore?.setFilters;
+     hasChanges = true;
    }

    if (refineTable?.refineCore?.setSorters !== setSortersRef.current) {
      setSortersRef.current = refineTable?.refineCore?.setSorters;
+     hasChanges = true;
    }

    // Deep compare filters to prevent false positives
    const newFilters = refineTable?.refineCore?.filters || [];
    const filtersChanged = !deepEqual(prevFiltersRef.current, newFilters);

    if (filtersChanged) {
      filtersRef.current = newFilters;
      prevFiltersRef.current = newFilters;
+     hasChanges = true;
    }

    // Deep compare sorters to prevent false positives
    const newSorters = refineTable?.refineCore?.sorters || [];
    const sortersChanged = !deepEqual(prevSortersRef.current, newSorters);

    if (sortersChanged) {
      sortersRef.current = newSorters;
      prevSortersRef.current = newSorters;
+     hasChanges = true;
    }

    // Always update these refs as they may change reference without content change
-   refineTableRef.current = refineTable;
-   tableQueryRef.current = refineTable?.refineCore?.tableQuery;
+   const prevRefineTable = refineTableRef.current;
+   const prevTableQuery = tableQueryRef.current;
+   refineTableRef.current = refineTable;
+   tableQueryRef.current = refineTable?.refineCore?.tableQuery;
+   if (prevRefineTable !== refineTable || prevTableQuery !== refineTable?.refineCore?.tableQuery) {
+     hasChanges = true;
+   }

    // Signal that refs have been updated
-   setVersion((v) => v + 1);
+   if (hasChanges) {
+     setVersion((v) => v + 1);
+   }
  }, [refineTable]);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb86869 and 9c5a4b8.

📒 Files selected for processing (1)
  • libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (4 hunks)
🔇 Additional comments (2)
libs/portal-framework-ui/src/components/data-table/contexts/RefineTable.tsx (2)

8-10: LGTM: Import updates align with v4 API.

The addition of useState and the migration of UseTableReturnType from @refinedev/core to @refinedev/react-table correctly reflect the v4 API structure described in the PR objectives.


15-17: LGTM: Type signatures correctly reference refineCore paths.

The updated type definitions for setFilters and setSorters using indexed access (UseTableReturnType<TData, any>["refineCore"]["setFilters"]) properly align with the v4 API where these properties are nested under refineCore.

Also applies to: 29-29

…nges

- Introduced `hasChanges` flag to track actual ref updates
- Prevents unnecessary version increments when no meaningful changes occur
- Optimizes performance by reducing unnecessary re-renders
@pcfreak30
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Dec 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@pcfreak30 pcfreak30 merged commit e5eb04a into develop Dec 8, 2025
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant