From 545b826e8509532934a514f79c936fc1186cf1d3 Mon Sep 17 00:00:00 2001 From: Fabio Fesel Date: Sat, 27 Aug 2022 13:57:29 +0200 Subject: [PATCH] Add memoization to useAwaitAction (#1) * Add memoization to useAwaitAction * Remove type assertion * Add test for memoized hook * Add space to jsdoc comment --- src/useAwaitAction.spec.tsx | 36 +++++++++++++++++++++++++++++++++++- src/useAwaitAction.ts | 9 +++++++-- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/useAwaitAction.spec.tsx b/src/useAwaitAction.spec.tsx index d9e5f5a..049c4b7 100644 --- a/src/useAwaitAction.spec.tsx +++ b/src/useAwaitAction.spec.tsx @@ -1,4 +1,4 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect, DispatchProp, Provider } from 'react-redux'; import { act } from 'react-dom/test-utils'; import { render } from '@testing-library/react'; @@ -213,4 +213,38 @@ describe('useAwaitAction', () => { console.error = errorHandler; // eslint-disable-line no-console }); + + it('Should not re-initialize when storeAwait when component re-renders', async () => { + const renderCounter = jest.fn(); + + /** + * - + * @returns TestComponent + */ + const TestComponent = (): any => { + const storeAwait = useAwaitAction(); + const [, triggerRender] = useState(); + + useEffect(() => { + triggerRender(null); + }); + + useEffect(() => { + renderCounter(); + }, [storeAwait]); + + return null; + }; + + act(() => { + render( + + + + + , + ); + }); + expect(renderCounter).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/useAwaitAction.ts b/src/useAwaitAction.ts index b4ec689..ae32d4d 100644 --- a/src/useAwaitAction.ts +++ b/src/useAwaitAction.ts @@ -1,5 +1,5 @@ +import { useMemo, useContext } from 'react'; import { Action } from 'redux'; -import { useContext } from 'react'; import { useStore } from 'react-redux'; import { AwaitEventEmitterContext } from './context/awaitEventEmitterContext'; import { ActionTypes, createAwaitAction } from './createAwaitAction'; @@ -15,5 +15,10 @@ export function useAwaitAction(): (s: ActionTypes, e? if (!eventEmitter) throw new Error('You need to access the await inside the component'); - return createAwaitAction(store, eventEmitter); + const awaitAction: (s: ActionTypes, e?: ActionTypes | undefined) => Promise = useMemo( + () => createAwaitAction(store, eventEmitter), + [store, eventEmitter], + ); + + return awaitAction; }