Skip to content

Commit 83a09dc

Browse files
rhamiltoclaude
andcommitted
fix(BulkSelect): hoist default label functions to prevent useMemo invalidation
The inline arrow function defaults were creating new function references on every render, breaking useMemo optimization. This caused dropdown items to recompute on every render instead of only when dependencies changed. Fixed by hoisting default label functions to module-level constants, ensuring stable references across renders and proper memoization. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent c02b6a0 commit 83a09dc

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

packages/module/src/BulkSelect/BulkSelect.tsx

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ export const BulkSelectValue = {
2222

2323
export type BulkSelectValue = (typeof BulkSelectValue)[keyof typeof BulkSelectValue];
2424

25+
const defaultSelectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`;
26+
const defaultSelectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`;
27+
const defaultSelectedLabel = (count: number) => `${count} selected`;
28+
2529
/** extends DropdownProps */
2630
export interface BulkSelectProps extends Omit<DropdownProps, 'toggle' | 'onSelect'> {
2731
/** BulkSelect className */
@@ -74,13 +78,17 @@ export const BulkSelect: FC<BulkSelectProps> = ({
7478
dropdownListProps,
7579
menuToggleProps,
7680
selectNoneLabel = 'Select none (0)',
77-
selectPageLabel = (pageCount?: number) => `Select page${pageCount ? ` (${pageCount})` : ''}`,
78-
selectAllLabel = (totalCount?: number) => `Select all${totalCount ? ` (${totalCount})` : ''}`,
79-
selectedLabel = (count: number) => `${count} selected`,
81+
selectPageLabel = defaultSelectPageLabel,
82+
selectAllLabel = defaultSelectAllLabel,
83+
selectedLabel = defaultSelectedLabel,
8084
...props
8185
}: BulkSelectProps) => {
8286
const [ isOpen, setOpen ] = useState(false);
8387

88+
// Compute label text to use as memo dependencies for i18n support
89+
const selectPageLabelText = selectPageLabel(pageCount);
90+
const selectAllLabelText = selectAllLabel(totalCount);
91+
8492
const splitButtonDropdownItems = useMemo(
8593
() => (
8694
<>
@@ -89,17 +97,17 @@ export const BulkSelect: FC<BulkSelectProps> = ({
8997
</DropdownItem>
9098
{isDataPaginated && (
9199
<DropdownItem ouiaId={`${ouiaId}-select-page`} value={BulkSelectValue.page} key={BulkSelectValue.page}>
92-
{selectPageLabel(pageCount)}
100+
{selectPageLabelText}
93101
</DropdownItem>
94102
)}
95103
{canSelectAll && (
96104
<DropdownItem ouiaId={`${ouiaId}-select-all`} value={BulkSelectValue.all} key={BulkSelectValue.all}>
97-
{selectAllLabel(totalCount)}
105+
{selectAllLabelText}
98106
</DropdownItem>
99107
)}
100108
</>
101109
),
102-
[ isDataPaginated, canSelectAll, ouiaId, pageCount, totalCount, selectNoneLabel, selectPageLabel, selectAllLabel ]
110+
[ isDataPaginated, canSelectAll, ouiaId, selectNoneLabel, selectPageLabelText, selectAllLabelText ]
103111
);
104112

105113
const allOption = isDataPaginated ? BulkSelectValue.page : BulkSelectValue.all;

0 commit comments

Comments
 (0)