From 9e73f9ff8b2d8c26790e154dd3243e0c6b0c8e02 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Kaiser Date: Tue, 29 Mar 2022 15:19:29 +0200 Subject: [PATCH 1/2] Backport of #7443 to v3 --- packages/ra-core/src/controller/useListParams.ts | 7 +++++++ packages/ra-core/src/util/hooks.ts | 10 ++++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/ra-core/src/controller/useListParams.ts b/packages/ra-core/src/controller/useListParams.ts index 7faf4a7c3e4..c586c2f50d3 100644 --- a/packages/ra-core/src/controller/useListParams.ts +++ b/packages/ra-core/src/controller/useListParams.ts @@ -17,6 +17,7 @@ import queryReducer, { import { changeListParams, ListParams } from '../actions/listActions'; import { SortPayload, ReduxState, FilterPayload } from '../types'; import removeEmpty from '../util/removeEmpty'; +import { useIsMounted } from '../util/hooks'; interface ListParamsOptions { resource: string; @@ -126,6 +127,7 @@ const useListParams = ({ shallowEqual ); const tempParams = useRef(); + const isMounted = useIsMounted(); const requestSignature = [ location.search, @@ -164,6 +166,11 @@ const useListParams = ({ }, [location.search]); // eslint-disable-line const changeParams = useCallback(action => { + // do not change params if the component is already unmounted + // this is necessary because changeParams can be debounced, and therefore + // executed after the component is unmounted + if (!isMounted.current) return; + if (!tempParams.current) { // no other changeParams action dispatched this tick tempParams.current = queryReducer(query, action); diff --git a/packages/ra-core/src/util/hooks.ts b/packages/ra-core/src/util/hooks.ts index 83c717b7878..8b44ae67d99 100644 --- a/packages/ra-core/src/util/hooks.ts +++ b/packages/ra-core/src/util/hooks.ts @@ -62,3 +62,13 @@ export function useTimeout(ms = 0) { return ready; } + +export function useIsMounted() { + const isMounted = useRef(true); + useEffect(() => { + return () => { + isMounted.current = false; + }; + }, []); + return isMounted; +} From ca0c687666b41eb7c13b6d30321745eb077fd19b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Kaiser Date: Wed, 30 Mar 2022 15:35:01 +0200 Subject: [PATCH 2/2] fix e2e list filter test --- cypress/integration/list.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cypress/integration/list.js b/cypress/integration/list.js index 8a1b8753154..34b04a57e08 100644 --- a/cypress/integration/list.js +++ b/cypress/integration/list.js @@ -102,13 +102,19 @@ describe('List Page', () => { LoginPage.login('admin', 'password'); ListPagePosts.navigate(); ListPagePosts.showFilter('title'); + // Let's clear the filter first, otherwise we have no way of knowing when the new filter has been (debounced and) applied + ListPagePosts.setFilterValue('title', ''); + cy.contains('1-10 of 13'); + // Now let's change the filter to something different than the default value ListPagePosts.setFilterValue( 'title', 'Omnis voluptate enim similique est possimus' ); cy.contains('1-1 of 1'); + // Navigate away and then back cy.get('[href="#/users"]').click(); cy.get('[href="#/posts"]').click(); + // Check that our filter has been preserved cy.get(ListPagePosts.elements.filter('title')).should(el => expect(el).to.have.value( 'Omnis voluptate enim similique est possimus'