-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Allow useSelect per store * New signature: useSelect( 'store', mapSelect, deps ) * Hopefully fix mobile tests * Propose useStoreSelectors * Revert README * Add comment * Remove shorthand notation and add unit tests * Update README * Remove now unrelated change * Updated docstring * Updated tests * Use renderHook from react testing library * Add usage example * Updated doc * Update CHANGELOG.md
- Loading branch information
Showing
7 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/** | ||
* Internal dependencies | ||
*/ | ||
import useSelect from '../use-select'; | ||
|
||
/** | ||
* Custom react hook for retrieving selectors from registered stores | ||
* | ||
* @param {string} storeKey Store to return selectors from. | ||
* @param {Function} mapSelectors Function called on every state change. The | ||
* returned value is exposed to the component | ||
* implementing this hook. The function receives | ||
* the object with all the store selectors as | ||
* its only argument. | ||
* @param {Array} deps If provided, this memoizes the mapSelect so the | ||
* same `mapSelect` is invoked on every state | ||
* change unless the dependencies change. | ||
* | ||
* @example | ||
* ```js | ||
* const { useStoreSelectors } = wp.data; | ||
* | ||
* function HammerPriceDisplay( { currency } ) { | ||
* const price = useStoreSelectors( | ||
* 'my-shop', | ||
* ( { getPrice } ) => getPrice( 'hammer', currency ), | ||
* [ currency ] | ||
* ); | ||
* return new Intl.NumberFormat( 'en-US', { | ||
* style: 'currency', | ||
* currency, | ||
* } ).format( price ); | ||
* } | ||
* | ||
* // Rendered in the application: | ||
* // <HammerPriceDisplay currency="USD" /> | ||
* ``` | ||
* | ||
* In the above example, when `HammerPriceDisplay` is rendered into an | ||
* application, the price will be retrieved from the store state using the | ||
* `mapSelectors` callback on `useStoreSelectors`. If the currency prop changes then | ||
* any price in the state for that currency is retrieved. If the currency prop | ||
* doesn't change and other props are passed in that do change, the price will | ||
* not change because the dependency is just the currency. | ||
* | ||
* @return {Function} A custom react hook. | ||
*/ | ||
export default function useStoreSelectors( storeKey, mapSelectors, deps = [] ) { | ||
return useSelect( ( select ) => mapSelectors( select( storeKey ) ), deps ); | ||
} |
45 changes: 45 additions & 0 deletions
45
packages/data/src/components/use-store-selectors/test/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { renderHook } from '@testing-library/react-hooks'; | ||
|
||
/** | ||
* WordPress dependencies | ||
*/ | ||
import { RegistryProvider } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { createRegistry } from '../../../registry'; | ||
import useStoreSelectors from '../index'; | ||
|
||
describe( 'useStoreSelectors', () => { | ||
let registry; | ||
beforeEach( () => { | ||
registry = createRegistry(); | ||
} ); | ||
|
||
it( 'wraps useSelect', () => { | ||
registry.registerStore( 'testStore', { | ||
reducer: () => ( { foo: 'bar' } ), | ||
selectors: { | ||
testSelector: ( state, key ) => state[ key ], | ||
}, | ||
} ); | ||
|
||
const wrapper = ( { children } ) => ( | ||
<RegistryProvider value={ registry }>{ children }</RegistryProvider> | ||
); | ||
|
||
const useHook = () => | ||
useStoreSelectors( 'testStore', ( { testSelector } ) => | ||
testSelector( 'foo' ) | ||
); | ||
|
||
const { result } = renderHook( useHook, { wrapper } ); | ||
|
||
// ensure expected state was rendered | ||
expect( result.current ).toEqual( 'bar' ); | ||
} ); | ||
} ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters