From de14b77afd639c340098737383b08c11d46f8432 Mon Sep 17 00:00:00 2001 From: Ferit Date: Fri, 23 Oct 2026 18:32:07 +0300 Subject: [PATCH] fix: memoize onTabClick callback reference with useEvent --- src/Tabs.tsx | 6 +++--- tests/index.test.tsx | 11 +++++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Tabs.tsx b/src/Tabs.tsx index 8fa6e5f5..df68b712 100644 --- a/src/Tabs.tsx +++ b/src/Tabs.tsx @@ -1,6 +1,6 @@ // Accessibility https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/Tab_Role import { clsx } from 'clsx'; -import { isMobile, useControlledState } from '@rc-component/util'; +import { isMobile, useControlledState, useEvent } from '@rc-component/util'; import * as React from 'react'; import { useEffect, useState } from 'react'; import TabContext from './TabContext'; @@ -159,14 +159,14 @@ const Tabs = React.forwardRef((props, ref) => { }, []); // ======================== Events ======================== - function onInternalTabClick(key: string, e: React.MouseEvent | React.KeyboardEvent) { + const onInternalTabClick = useEvent((key: string, e: React.MouseEvent | React.KeyboardEvent) => { onTabClick?.(key, e); const isActiveChanged = key !== mergedActiveKey; setMergedActiveKey(key); if (isActiveChanged) { onChange?.(key); } - } + }); // ======================== Render ======================== const sharedProps = { diff --git a/tests/index.test.tsx b/tests/index.test.tsx index 2d5029e6..65893fb7 100644 --- a/tests/index.test.tsx +++ b/tests/index.test.tsx @@ -310,6 +310,17 @@ describe('Tabs.Basic', () => { expect(container.querySelector('.my-node')).toBeTruthy(); expect(renderTabBar).toHaveBeenCalled(); }); + + it('keep onTabClick reference stable across renders', () => { + const onTabClickList: any[] = []; + const renderTabBar = jest.fn((props, Component) => { + onTabClickList.push(props.onTabClick); + return ; + }); + const { rerender } = render(getTabs({ renderTabBar, className: 'first' })); + rerender(getTabs({ renderTabBar, className: 'second' })); + expect(onTabClickList[0]).toBe(onTabClickList[1]); + }); }); it('destroyOnHidden', () => {