Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions data/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ Let's say the state of our plugin (registered with the key `myPlugin`) has the f
wp.data.registerSelectors( 'myPlugin', { getTitle: ( state ) => state.title } );
```

### `wp.data.select( key: string, selectorName: string, ...args )`
### `wp.data.select( key: string )`

This function allows calling any registered selector. Given a module's key, a selector's name and extra arguments passed to the selector, this function calls the selector passing it the current state and the extra arguments provided.
This function allows calling any registered selector. Given a module's key, this function returns an object of all selector functions registered for the module.

#### Example:

```js
wp.data.select( 'myPlugin', 'getTitle' ); // Returns "My post title"
wp.data.select( 'myPlugin' ).getTitle(); // Returns "My post title"
```

### `wp.data.query( mapSelectorsToProps: function )( WrappedComponent: Component )`
Expand All @@ -58,7 +58,7 @@ const Component = ( { title } ) => <div>{ title }</div>;

wp.data.query( select => {
return {
title: select( 'myPlugin', 'getTitle' ),
title: select( 'myPlugin' ).getTitle(),
};
} )( Component );
```
Expand All @@ -71,7 +71,7 @@ Function used to subscribe to data changes. The listener function is called each
// Subscribe.
const unsubscribe = wp.data.subscribe( () => {
const data = {
slug: wp.data.select( 'core/editor', 'getEditedPostSlug' ),
slug: wp.data.select( 'core/editor' ).getEditedPostSlug(),
};

console.log( 'data changed', data );
Expand Down
45 changes: 26 additions & 19 deletions data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,32 @@ export function registerReducer( reducerKey, reducer ) {
* state as first argument.
*/
export function registerSelectors( reducerKey, newSelectors ) {
selectors[ reducerKey ] = newSelectors;
const store = stores[ reducerKey ];
const createStateSelector = ( selector ) => ( ...args ) => selector( store.getState(), ...args );
selectors[ reducerKey ] = mapValues( newSelectors, createStateSelector );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I wanted to avoid having to create a wrapper for each selector but I do see the DevX benefits from this new API

}

/**
* Calls a selector given the current state and extra arguments.
*
* @param {string} reducerKey Part of the state shape to register the
* selectors for.
*
* @return {*} The selector's returned value.
*/
export function select( reducerKey ) {
if ( arguments.length > 1 ) {
// eslint-disable-next-line no-console
console.warn(
'Deprecated: `select` now accepts only a single argument: the reducer key. ' +
'The return value is an object of selector functions.'
);

const [ , selectorKey, ...args ] = arguments;
return select( reducerKey )[ selectorKey ]( ...args );
}

return selectors[ reducerKey ];
}

/**
Expand Down Expand Up @@ -100,24 +125,6 @@ export const query = ( mapSelectorsToProps ) => ( WrappedComponent ) => {
};

return connectWithStore( ( state, ownProps ) => {
const select = ( key, selectorName, ...args ) => {
return selectors[ key ][ selectorName ]( state[ key ], ...args );
};

return mapSelectorsToProps( select, ownProps );
} );
};

/**
* Calls a selector given the current state and extra arguments.
*
* @param {string} reducerKey Part of the state shape to register the
* selectors for.
* @param {string} selectorName Selector name.
* @param {*} args Selectors arguments.
*
* @return {*} The selector's returned value.
*/
export const select = ( reducerKey, selectorName, ...args ) => {
return selectors[ reducerKey ][ selectorName ]( stores[ reducerKey ].getState(), ...args );
};
19 changes: 15 additions & 4 deletions data/test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,23 @@ describe( 'select', () => {
selector2,
} );

expect( select( 'reducer1', 'selector1' ) ).toEqual( 'result1' );
expect( select( 'reducer1' ).selector1() ).toEqual( 'result1' );
expect( selector1 ).toBeCalledWith( store.getState() );

expect( select( 'reducer1', 'selector2' ) ).toEqual( 'result2' );
expect( select( 'reducer1' ).selector2() ).toEqual( 'result2' );
expect( selector2 ).toBeCalledWith( store.getState() );
} );

it( 'provides upgrade path for deprecated usage', () => {
const store = registerReducer( 'reducer', () => 'state' );
const selector = jest.fn( () => 'result' );

registerSelectors( 'reducer', { selector } );

expect( select( 'reducer', 'selector', 'arg' ) ).toEqual( 'result' );
expect( selector ).toBeCalledWith( store.getState(), 'arg' );
expect( console ).toHaveWarned();
} );
} );

describe( 'query', () => {
Expand All @@ -48,7 +59,7 @@ describe( 'query', () => {
} );
const Component = query( ( selectFunc, ownProps ) => {
return {
data: selectFunc( 'reactReducer', 'reactSelector', ownProps.keyName ),
data: selectFunc( 'reactReducer' ).reactSelector( ownProps.keyName ),
};
} )( ( props ) => {
return <div>{ props.data }</div>;
Expand All @@ -68,7 +79,7 @@ describe( 'subscribe', () => {
globalSelector: ( state ) => state,
} );
const unsubscribe = subscribe( () => {
incrementedValue = select( 'myAwesomeReducer', 'globalSelector' );
incrementedValue = select( 'myAwesomeReducer' ).globalSelector();
} );
const action = { type: 'dummy' };

Expand Down
2 changes: 1 addition & 1 deletion edit-post/components/sidebar/featured-image/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function FeaturedImage( { isOpened, postType, onTogglePanel } ) {
}

const applyQuery = query( ( select ) => ( {
postTypeSlug: select( 'core/editor', 'getEditedPostAttribute', 'type' ),
postTypeSlug: select( 'core/editor' ).getEditedPostAttribute( 'type' ),
} ) );

const applyConnect = connect(
Expand Down
2 changes: 1 addition & 1 deletion edit-post/components/sidebar/header.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const SidebarHeader = ( { panel, onSetPanel, onToggleSidebar, count } ) => {

export default compose(
query( ( select ) => ( {
count: select( 'core/editor', 'getSelectedBlockCount' ),
count: select( 'core/editor' ).getSelectedBlockCount(),
} ) ),
connect(
( state ) => ( {
Expand Down
2 changes: 1 addition & 1 deletion edit-post/components/sidebar/page-attributes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function PageAttributes( { isOpened, onTogglePanel, postType } ) {
}

const applyQuery = query( ( select ) => ( {
postTypeSlug: select( 'core/editor', 'getEditedPostAttribute', 'type' ),
postTypeSlug: select( 'core/editor' ).getEditedPostAttribute( 'type' ),
} ) );

const applyConnect = connect(
Expand Down
2 changes: 1 addition & 1 deletion editor/hooks/copy-content/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function CopyContentButton( { editedPostContent, hasCopied, setState } ) {

const Enhanced = compose(
query( ( select ) => ( {
editedPostContent: select( 'core/editor', 'getEditedPostAttribute', 'content' ),
editedPostContent: select( 'core/editor' ).getEditedPostAttribute( 'content' ),
} ) ),
withState( { hasCopied: false } )
)( CopyContentButton );
Expand Down