From fbba3f6476b4815db413dc09df12d727ee20e7e5 Mon Sep 17 00:00:00 2001 From: Jay Meistrich Date: Sun, 8 Oct 2023 22:21:38 +0200 Subject: [PATCH] change: For item component takes an item$ parameter instead of item --- src/react/For.tsx | 28 +++++++++++++++++++++------- tests/react.test.ts | 22 +++++++++++----------- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/react/For.tsx b/src/react/For.tsx index ac0dd2069..24f44c725 100644 --- a/src/react/For.tsx +++ b/src/react/For.tsx @@ -6,6 +6,11 @@ import { useSelector } from './useSelector'; const autoMemoCache = new Map, FC>(); +type ForItemProps = { + item$: Observable; + id?: string; +} & TProps; + export function For({ each, optimized: isOptimized, @@ -16,10 +21,10 @@ export function For({ }: { each?: ObservableReadable | Map>; optimized?: boolean; - item?: FC<{ item: Observable; id?: string } & TProps>; + item?: FC>; itemProps?: TProps; sortValues?: (A: T, B: T, AKey: string, BKey: string) => number; - children?: (value: Observable) => ReactElement; + children?: (value: Observable, id: string | undefined) => ReactElement; }): ReactElement | null { if (!each) return null; @@ -30,10 +35,10 @@ export function For({ // The child function gets wrapped in a memoized observer component if (!item && children) { // Update the ref so the generated component uses the latest function - const refChildren = useRef<(value: Observable) => ReactElement>(); + const refChildren = useRef<(value: Observable, id: string | undefined) => ReactElement>(); refChildren.current = children; - item = useMemo(() => observer(({ item }) => refChildren.current!(item)), []); + item = useMemo(() => observer(({ item$, id }) => refChildren.current!(item$, id)), []); } else { // @ts-expect-error $$typeof is private if (item.$$typeof !== Symbol.for('react.memo')) { @@ -72,7 +77,14 @@ export function For({ if (value[i]) { const val = value[i]; const key = (isIdFieldFunction ? idField(val) : (val as Record)[idField as string]) ?? i; - const props = { key, id: key, item: (each as Observable)[i] }; + const item$ = (each as Observable)[i]; + // TODOV3 Remove item + const props: ForItemProps & { key: string; item: Observable } = { + key, + id: key, + item$, + item: item$, + }; out.push(createElement(item as FC, itemProps ? Object.assign(props, itemProps) : props)); } @@ -87,10 +99,12 @@ export function For({ for (let i = 0; i < keys.length; i++) { const key = keys[i]; if (isMap ? value.get(key) : value[key]) { - const props = { + const item$ = isMap ? each!.get(key) : (each as ObservableObject>)[key]; + const props: ForItemProps & { key: string; item: Observable } = { key, id: key, - item: isMap ? each!.get(key) : (each as ObservableObject>)[key], + item$, + item: item$, }; out.push(createElement(item as FC, itemProps ? Object.assign(props, itemProps) : props)); } diff --git a/tests/react.test.ts b/tests/react.test.ts index 1f01ea350..8ff188b47 100644 --- a/tests/react.test.ts +++ b/tests/react.test.ts @@ -326,8 +326,8 @@ describe('For', () => { const obs = observable({ items: [{ id: 0, label: '0' }] as TestObject[], }); - function Item({ item }: { item: Observable }) { - const data = useSelector(item); + function Item({ item$ }: { item$: Observable }) { + const data = useSelector(item$); return createElement('li', { id: data.id }, data.label); } function Test() { @@ -357,8 +357,8 @@ describe('For', () => { { id: 'A', label: 'A' }, ] as TestObject[], }); - function Item({ item }: { item: Observable }) { - const data = useSelector(item); + function Item({ item$ }: { item$: Observable }) { + const data = useSelector(item$); return createElement('li', { id: data.id }, data.label); } function Test() { @@ -401,9 +401,9 @@ describe('For', () => { { id: 'A', label: 'A' }, ] as TestObject[], }); - function Item({ item }: { item: Observable }) { - const data = useSelector(item); - return createElement('li', { id: getObservableIndex(item) }, data.label); + function Item({ item$ }: { item$: Observable }) { + const data = useSelector(item$); + return createElement('li', { id: getObservableIndex(item$) }, data.label); } function Test() { return createElement( @@ -426,8 +426,8 @@ describe('For', () => { ['m1', { label: 'A', id: 'A' }], ]), }); - function Item({ item }: { item: Observable }) { - const data = useSelector(item); + function Item({ item$ }: { item$: Observable }) { + const data = useSelector(item$); return createElement('li', { id: data.label }, data.label); } function Test() { @@ -451,8 +451,8 @@ describe('For', () => { ['m1', { label: 'A', id: 'A' }], ]), }); - function Item({ item }: { item: Observable }) { - const data = useSelector(item); + function Item({ item$ }: { item$: Observable }) { + const data = useSelector(item$); return createElement('li', { id: data.label }, data.label); } function Test() {