Skip to content

Commit

Permalink
Fix custom generic store without a unsubscribe function (#27634)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin940726 authored Dec 10, 2020
1 parent c7b6701 commit aaf2c01
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
3 changes: 2 additions & 1 deletion packages/data/src/components/use-select/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ export default function useSelect( _mapSelect, deps ) {

return () => {
isMountedAndNotUnsubscribing.current = false;
unsubscribers.forEach( ( unsubscribe ) => unsubscribe() );
// The return value of the subscribe function could be undefined if the store is a custom generic store.
unsubscribers.forEach( ( unsubscribe ) => unsubscribe?.() );
renderQueue.flush( queueContext );
};
}, [ registry, trapSelect, depsChangedFlag ] );
Expand Down
66 changes: 66 additions & 0 deletions packages/data/src/components/use-select/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -719,5 +719,71 @@ describe( 'useSelect', () => {
// Test if the unsubscribers get called correctly.
renderer.unmount();
} );

it( 'handles custom generic stores without a unsubscribe function', () => {
let renderer;

function createCustomStore() {
let storeChanged = () => {};
let counter = 0;

const selectors = {
getCounter: () => counter,
};

const actions = {
increment: () => {
counter += 1;
storeChanged();
},
};

return {
getSelectors() {
return selectors;
},
getActions() {
return actions;
},
subscribe( listener ) {
storeChanged = listener;
},
};
}

registry.registerGenericStore(
'generic-store',
createCustomStore()
);

const TestComponent = jest.fn( () => {
const state = useSelect(
( select ) => select( 'generic-store' ).getCounter(),
[]
);

return <div data={ state } />;
} );

act( () => {
renderer = TestRenderer.create(
<RegistryProvider value={ registry }>
<TestComponent />
</RegistryProvider>
);
} );

const testInstance = renderer.root;

expect( testInstance.findByType( 'div' ).props.data ).toBe( 0 );

act( () => {
registry.dispatch( 'generic-store' ).increment();
} );

expect( testInstance.findByType( 'div' ).props.data ).toBe( 1 );

expect( () => renderer.unmount() ).not.toThrow();
} );
} );
} );

0 comments on commit aaf2c01

Please sign in to comment.