-
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
Remove select() hack from getBlockEditingMode() #51359
Conversation
328e324
to
41c2532
Compare
Size Change: -3 B (0%) Total Size: 1.39 MB
ℹ️ View Unchanged
|
Flaky tests detected in e9855d2. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5218267083
|
unlock( store ).registerPrivateActions( privateActions ); | ||
unlock( store ).registerPrivateSelectors( privateSelectors ); | ||
|
||
register( 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.
You need to keep the legacy registerStore
here. Otherwise the persist
plugin won't be active. It works by overriding the registerStore
method of the registry
and reading the persist
option. If you call register
, the plugin won't catch it.
This will be solved once we finish migration of the block-editor
store to the preferences
package. It's being worked on in #39632.
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.
Ah, bummer, I see.
I don't think we can remove this workaround yet then because if we do this:
export const store = createReduxStore( STORE_NAME, {
...storeConfig,
persist: [ 'preferences' ],
} );
unlock( store ).registerPrivateActions( privateActions );
unlock( store ).registerPrivateSelectors( privateSelectors );
registerStore( STORE_NAME, {
...storeConfig,
persist: [ 'preferences' ],
} );
Then the private selectors are not callable from public selectors as they are not bound to the store that's created by registerStore
.
(When I try it I get a Uncaught TypeError: selector.registry is undefined
error on load.)
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.
I suppose we will wait until #39632 is merged!
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.
I did start looking at #39632 one again. I've rebased it and hope to push some further options this week.
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.
Then the private selectors are not callable from public selectors as they are not bound to the store that's created by
registerStore
.
Oh, there are two gotchas at work here:
- Registering private selectors on the
store
object is a noop, because the store is not instantiated from that object! It's just a store descriptor object that's exported so that users can pass it to functions likeselect( store )
ordispatch( store )
. The descriptor has an.instantiate
method, but it's never called. TheregisterStore
function creates a second store descriptor fromSTORE_NAME
andstoreConfig
, and uses that internal one to actually instantiate the store. But that descriptor doesn't have any private selectors registered. - To get the private selectors pre-bound to the registry, they need to be registered after
createReduxStore
and before the.instantiate
function is called, butregisterStore
calls them both within one statement:gutenberg/packages/data/src/registry.js
Line 310 in 4d0f303
createReduxStore( storeName, options ).instantiate( registry )
state.blockListSettings, | ||
] | ||
export const getBlockEditingMode = createRegistrySelector( ( select ) => | ||
createSelector( |
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.
This memoization won't work because createSelector
is called again and again on each call of getBlockEditingMode
, creating a new instance with its own memoization cache each time.
createRegistrySelector
is like:
createRegistrySelector = ( selectorFactory ) => ( ...args ) => selectorFactory( registry.select )( ...args );
I don't know how to solve this, maybe we'll need to patch createRegistrySelector
to call the "factory" function only once.
state.blocks.parents, | ||
state.settings.templateLock, | ||
state.blockListSettings, | ||
] |
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.
I'm not sure if memoizing this selector is even a good idea. This particular implementation won't catch changes in select( blockStore ).hasContentRoleAttribute( name )
. It's very unlikely that a block's registration properties would change, but still.
The selector doesn't do any very complex calculation, and the return value is a string, which doesn't need an unique identity. Let's just remove the createSelector
memoization.
What?
Now that #51051 is merged we can remove a hack that I added in #51148 to work around an issue with private registry selectors (described here: #50985).
Why?
Relying on the global
select
function is never ideal asselect
may differ if the selector is ran within a differentRegistryProvider
context.How?
Use
createRegistrySelector
again.The way that #51051 is designed means that we have to update
block-editor
to register private selectors and actions before it registers the store.Despite the inline comment to the contrary I don't think using
register()
instead ofregisterStore()
will actually make any difference because both functions result in the same execution ofregisterStoreInstance
internally.gutenberg/packages/data/src/registry.js
Lines 304 to 313 in f9e405e
gutenberg/packages/data/src/registry.js
Lines 282 to 286 in f9e405e
Testing Instructions
Same as in #50857.