Skip to content

Commit

Permalink
@wordpress/data: Handle more return type values from a mapSelect argu…
Browse files Browse the repository at this point in the history
…ment on useSelect (#16669)
  • Loading branch information
nerrad authored and gziolo committed Aug 29, 2019
1 parent 0066b77 commit 9570b2f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 7 deletions.
13 changes: 6 additions & 7 deletions packages/data/src/components/use-select/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
useEffect,
useReducer,
} from '@wordpress/element';
import { isShallowEqualObjects } from '@wordpress/is-shallow-equal';
import isShallowEqual from '@wordpress/is-shallow-equal';

/**
* Internal dependencies
Expand Down Expand Up @@ -90,16 +90,15 @@ export default function useSelect( _mapSelect, deps ) {
let mapOutput;

try {
if (
latestMapSelect.current !== mapSelect ||
latestMapOutputError.current
) {
if ( latestMapSelect.current !== mapSelect || latestMapOutputError.current ) {
mapOutput = mapSelect( registry.select, registry );
} else {
mapOutput = latestMapOutput.current;
}
} catch ( error ) {
let errorMessage = `An error occurred while running 'mapSelect': ${ error.message }`;
let errorMessage = `An error occurred while running 'mapSelect': ${
error.message
}`;

if ( latestMapOutputError.current ) {
errorMessage += `\nThe error may be correlated with this previous error:\n`;
Expand Down Expand Up @@ -129,7 +128,7 @@ export default function useSelect( _mapSelect, deps ) {
registry.select,
registry
);
if ( isShallowEqualObjects( latestMapOutput.current, newMapOutput ) ) {
if ( isShallowEqual( latestMapOutput.current, newMapOutput ) ) {
return;
}
latestMapOutput.current = newMapOutput;
Expand Down
86 changes: 86 additions & 0 deletions packages/data/src/components/use-select/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,5 +132,91 @@ describe( 'useSelect', () => {
children: 'bar',
} );
} );
describe( 'rerenders as expected with various mapSelect return types', () => {
const getComponent = ( mapSelectSpy ) => () => {
const data = useSelect( mapSelectSpy, [] );
return <div data={ data } />;
};
let subscribedSpy, TestComponent;
const mapSelectSpy = jest.fn(
( select ) => select( 'testStore' ).testSelector()
);
const selectorSpy = jest.fn();
const subscribeCallback = ( subscription ) => {
subscribedSpy = subscription;
};

beforeEach( () => {
registry.registerStore( 'testStore', {
reducer: () => null,
selectors: {
testSelector: selectorSpy,
},
} );
registry.subscribe = subscribeCallback;
TestComponent = getComponent( mapSelectSpy );
} );
afterEach( () => {
selectorSpy.mockClear();
mapSelectSpy.mockClear();
} );

it.each( [
[
'boolean',
[ false, true ],
],
[
'number',
[ 10, 20 ],
],
[
'string',
[ 'bar', 'cheese' ],
],
[
'array',
[ [ 10, 20 ], [ 10, 30 ] ],
],
[
'object',
[ { foo: 'bar' }, { foo: 'cheese' } ],
],
[
'null',
[ null, undefined ],
],
[
'undefined',
[ undefined, 42 ],
],
] )( 'renders as expected with %s return values', (
type,
testValues,
) => {
const [ valueA, valueB ] = testValues;
selectorSpy.mockReturnValue( valueA );
let renderer;
act( () => {
renderer = TestRenderer.create(
<RegistryProvider value={ registry }>
<TestComponent />
</RegistryProvider>
);
} );
const testInstance = renderer.root;
// ensure expected state was rendered.
expect( testInstance.findByType( 'div' ).props.data ).toEqual( valueA );

// Update the returned value from the selector and trigger the
// subscription which should in turn trigger a re-render.
act( () => {
selectorSpy.mockReturnValue( valueB );
subscribedSpy();
} );
expect( testInstance.findByType( 'div' ).props.data ).toEqual( valueB );
expect( mapSelectSpy ).toHaveBeenCalledTimes( 3 );
} );
} );
} );

0 comments on commit 9570b2f

Please sign in to comment.