Skip to content

Commit 2087d5e

Browse files
committed
[hooks] Don't use GetId functions in handler memo
Fixes #152
1 parent 1371068 commit 2087d5e

File tree

2 files changed

+57
-25
lines changed

2 files changed

+57
-25
lines changed

src/ui-react/hooks.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,12 @@ import type {
212212
ResultTableCellIdsListener,
213213
ResultTableListener,
214214
} from '../@types/queries/index.d.ts';
215-
import {arrayIsEmpty, arrayIsEqual, arrayMap} from '../common/array.ts';
215+
import {
216+
arrayFilter,
217+
arrayIsEmpty,
218+
arrayIsEqual,
219+
arrayMap,
220+
} from '../common/array.ts';
216221
import {
217222
getUndefined,
218223
ifNotUndefined,
@@ -392,8 +397,15 @@ const useSetCallback = <Parameter, Thing>(
392397
),
393398
),
394399
),
395-
// eslint-disable-next-line react-hooks/exhaustive-deps
396-
[store, settable, ...getDeps, ...thenDeps, ...args],
400+
/* eslint-disable react-hooks/exhaustive-deps */
401+
[
402+
store,
403+
settable,
404+
...getDeps,
405+
...thenDeps,
406+
...arrayFilter(args, (arg) => !isFunction(arg)),
407+
],
408+
/* eslint-enable react-hooks/exhaustive-deps */
397409
);
398410
};
399411

test/unit/ui-react/hooks.test.tsx

Lines changed: 42 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2741,30 +2741,39 @@ describe('Write Hooks', () => {
27412741
expect(clickHandler1).not.toEqual(clickHandler2);
27422742
});
27432743

2744-
test('useSetTableCallback', () => {
2744+
test('useSetTableCallback (including handler memo)', () => {
27452745
const then = jest.fn((_store?: Store, _table?: Table) => null);
2746+
let previousHandler: any;
2747+
let handlerChanged = 0;
27462748
const Test = ({
27472749
value,
27482750
then,
27492751
}: {
27502752
readonly value: number;
27512753
readonly then: (store?: Store, table?: Table) => void;
27522754
}) => {
2753-
return (
2754-
<div
2755-
onClick={useSetTableCallback<React.MouseEvent<HTMLDivElement>>(
2756-
't1',
2757-
(e) => ({r1: {c1: e.screenX * value}}),
2758-
[value],
2759-
store,
2760-
then,
2761-
)}
2762-
/>
2755+
const handler = useSetTableCallback<React.MouseEvent<HTMLDivElement>>(
2756+
't1',
2757+
(e) => ({r1: {c1: e.screenX * value}}),
2758+
[value],
2759+
store,
2760+
then,
27632761
);
2762+
if (handler != previousHandler) {
2763+
handlerChanged++;
2764+
previousHandler = handler;
2765+
}
2766+
return <div onClick={handler} />;
27642767
};
27652768
act(() => {
27662769
renderer = create(<Test value={2} then={then} />);
27672770
});
2771+
expect(handlerChanged).toEqual(1);
2772+
2773+
act(() => {
2774+
renderer.update(<Test value={2} then={then} />);
2775+
});
2776+
expect(handlerChanged).toEqual(1);
27682777

27692778
const clickHandler1 = renderer.root.findByType('div').props.onClick;
27702779
act(() => {
@@ -2776,34 +2785,44 @@ describe('Write Hooks', () => {
27762785
act(() => {
27772786
renderer.update(<Test value={3} then={then} />);
27782787
});
2788+
expect(handlerChanged).toEqual(2);
27792789
const clickHandler2 = renderer.root.findByType('div').props.onClick;
27802790
expect(clickHandler1).not.toEqual(clickHandler2);
27812791
});
27822792

2783-
test('useSetTableCallback, parameterized Id', () => {
2793+
test('useSetTableCallback, parameterized Id (including handler memo)', () => {
27842794
const then = jest.fn((_store?: Store, _table?: Table) => null);
2795+
let previousHandler: any;
2796+
let handlerChanged = 0;
27852797
const Test = ({
27862798
value,
27872799
then,
27882800
}: {
27892801
readonly value: number;
27902802
readonly then: (store?: Store, table?: Table) => void;
27912803
}) => {
2792-
return (
2793-
<div
2794-
onClick={useSetTableCallback<React.MouseEvent<HTMLDivElement>>(
2795-
(e) => 't' + e.screenY,
2796-
(e) => ({r1: {c1: e.screenX * value}}),
2797-
[value],
2798-
store,
2799-
then,
2800-
)}
2801-
/>
2804+
const handler = useSetTableCallback<React.MouseEvent<HTMLDivElement>>(
2805+
(e) => 't' + e.screenY,
2806+
(e) => ({r1: {c1: e.screenX * value}}),
2807+
[value],
2808+
store,
2809+
then,
28022810
);
2811+
if (handler != previousHandler) {
2812+
handlerChanged++;
2813+
previousHandler = handler;
2814+
}
2815+
return <div onClick={handler} />;
28032816
};
28042817
act(() => {
28052818
renderer = create(<Test value={2} then={then} />);
28062819
});
2820+
expect(handlerChanged).toEqual(1);
2821+
2822+
act(() => {
2823+
renderer.update(<Test value={2} then={then} />);
2824+
});
2825+
expect(handlerChanged).toEqual(1);
28072826

28082827
const clickHandler1 = renderer.root.findByType('div').props.onClick;
28092828
act(() => {
@@ -2821,6 +2840,7 @@ describe('Write Hooks', () => {
28212840
act(() => {
28222841
renderer.update(<Test value={3} then={then} />);
28232842
});
2843+
expect(handlerChanged).toEqual(2);
28242844
const clickHandler2 = renderer.root.findByType('div').props.onClick;
28252845
expect(clickHandler1).not.toEqual(clickHandler2);
28262846
});

0 commit comments

Comments
 (0)