diff --git a/spec/tests/Iterate.spec.tsx b/spec/tests/Iterate.spec.tsx index 432a9d1..cc4f67c 100644 --- a/spec/tests/Iterate.spec.tsx +++ b/spec/tests/Iterate.spec.tsx @@ -667,6 +667,42 @@ describe('`Iterate` component', () => { ); } ); + + it( + gray( + 'When given iterable yields consecutive identical values the hook will not consequently re-render' + ), + async () => { + let timesRerendered = 0; + let lastRenderFnInput: undefined | IterationResult; + const channel = new IterableChannelTestHelper(); + + const rendered = render( + + {next => { + timesRerendered++; + lastRenderFnInput = next; + return
Render count: {timesRerendered}
; + }} +
+ ); + + for (let i = 0; i < 3; ++i) { + await act(() => channel.put('a')); + } + + expect(timesRerendered).toStrictEqual(2); + expect(lastRenderFnInput).toStrictEqual({ + value: 'a', + pendingFirst: false, + done: false, + error: undefined, + }); + expect(rendered.container.innerHTML).toStrictEqual( + '
Render count: 2
' + ); + } + ); }); const simulatedError = new Error('🚨 Simulated Error 🚨'); diff --git a/spec/tests/useAsyncIter.spec.ts b/spec/tests/useAsyncIter.spec.ts index 5243b04..a4fe16a 100644 --- a/spec/tests/useAsyncIter.spec.ts +++ b/spec/tests/useAsyncIter.spec.ts @@ -471,6 +471,33 @@ describe('`useAsyncIter` hook', () => { }); } ); + + it( + gray( + 'When given iterable yields consecutive identical values the hook will not consequently re-render' + ), + async () => { + let timesRerendered = 0; + const channel = new IterableChannelTestHelper(); + + const renderedHook = renderHook(() => { + timesRerendered++; + return useAsyncIter(channel); + }); + + for (let i = 0; i < 3; ++i) { + await act(() => channel.put('a')); + } + + expect(timesRerendered).toStrictEqual(2); + expect(renderedHook.result.current).toStrictEqual({ + value: 'a', + pendingFirst: false, + done: false, + error: undefined, + }); + } + ); }); const simulatedError = new Error('🚨 Simulated Error 🚨'); diff --git a/src/useAsyncIter/index.ts b/src/useAsyncIter/index.ts index a93fcb1..7fba0cf 100644 --- a/src/useAsyncIter/index.ts +++ b/src/useAsyncIter/index.ts @@ -169,13 +169,15 @@ const useAsyncIter: { iterationIdx++ ) ?? (value as ExtractAsyncIterValue); - stateRef.current = { - value: formattedValue, - pendingFirst: false, - done: false, - error: undefined, - }; - rerender(); + if (!Object.is(formattedValue, stateRef.current.value)) { + stateRef.current = { + value: formattedValue, + pendingFirst: false, + done: false, + error: undefined, + }; + rerender(); + } } } if (!iteratorClosedByConsumer) {