-
Notifications
You must be signed in to change notification settings - Fork 4.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Data: refuse to register an already registered store #49134
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -211,10 +211,18 @@ export function createRegistry( storeConfigs = {}, parent = null ) { | |
/** | ||
* Registers a store instance. | ||
* | ||
* @param {string} name Store registry name. | ||
* @param {Object} store Store instance object (getSelectors, getActions, subscribe). | ||
* @param {string} name Store registry name. | ||
* @param {Function} createStore Function that creates a store object (getSelectors, getActions, subscribe). | ||
*/ | ||
function registerStoreInstance( name, store ) { | ||
function registerStoreInstance( name, createStore ) { | ||
if ( stores[ name ] ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this change is worth a unit test. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, added a unit test that checks that after a second registration the old data are still there. |
||
// eslint-disable-next-line no-console | ||
console.error( 'Store "' + name + '" is already registered.' ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be an info or warning call instead? IMO, we want this to be a supported option for stores |
||
return stores[ name ]; | ||
} | ||
|
||
const store = createStore(); | ||
|
||
if ( typeof store.getSelectors !== 'function' ) { | ||
throw new TypeError( 'store.getSelectors must be a function' ); | ||
} | ||
|
@@ -262,6 +270,8 @@ export function createRegistry( storeConfigs = {}, parent = null ) { | |
// ignore it. | ||
} | ||
} | ||
|
||
return store; | ||
} | ||
|
||
/** | ||
|
@@ -270,15 +280,17 @@ export function createRegistry( storeConfigs = {}, parent = null ) { | |
* @param {StoreDescriptor} store Store descriptor. | ||
*/ | ||
function register( store ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I possibly mis-understand this! The extra instance from the second bundle wouldn't ever be instantiated. If that's a problem, should we also return the already registered store here? Then, at least the second store instance could get assigned to the one stored in the registry. I guess that would make the consumer look more like Happy to be corrected on this; I don't understand the internals of store registration that well :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The The function register() {
const plansStore = createReduxStore( STORE_NAME, ... );
register( plansStore );
return plansStore;
} and then use as: const PLANS_STORE = Plans.register();
registry.select( PLANS_STORE ).getPlanProduct( ... ); The legacy There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Ah, now I understand :) Given this example: // store
export const fooStore = createReduxStore( ... );
register( fooStore );
// bundle1
import { fooStore as foo1 } from 'foo-store';
useSelect( select => select( foo1 ).selector() );
// bundle2
import { fooStore as foo2 } from 'foo-store';
useSelect( select => select( foo2 ).selector() ); If you were to somehow compare But realizing that |
||
registerStoreInstance( store.name, store.instantiate( registry ) ); | ||
registerStoreInstance( store.name, () => | ||
store.instantiate( registry ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great idea for the lazy init 👍 |
||
); | ||
} | ||
|
||
function registerGenericStore( name, store ) { | ||
deprecated( 'wp.data.registerGenericStore', { | ||
since: '5.9', | ||
alternative: 'wp.data.register( storeDescriptor )', | ||
} ); | ||
registerStoreInstance( name, store ); | ||
registerStoreInstance( name, () => store ); | ||
} | ||
|
||
/** | ||
|
@@ -294,10 +306,10 @@ export function createRegistry( storeConfigs = {}, parent = null ) { | |
throw new TypeError( 'Must specify store reducer' ); | ||
} | ||
|
||
const store = createReduxStore( storeName, options ).instantiate( | ||
registry | ||
const store = registerStoreInstance( storeName, () => | ||
createReduxStore( storeName, options ).instantiate( registry ) | ||
); | ||
registerStoreInstance( storeName, store ); | ||
|
||
return store.store; | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Such a change is worth a CHANGELOG entry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added ✅