Skip to content

Commit

Permalink
Try: Use createSelector
Browse files Browse the repository at this point in the history
  • Loading branch information
SantosGuillamot committed Oct 3, 2024
1 parent 8b494c6 commit e9e00d4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 41 deletions.
25 changes: 16 additions & 9 deletions packages/block-editor/src/hooks/block-bindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
* whenever there are updates in block context.
* `source.getFieldsList` may also call a selector via `registry.select`.
*/
// A constant object needs to be used to avoid unnecessary re-renders.
const context = {};
const fieldsList = useSelect(
( select ) => {
if ( ! bindableAttributes || bindableAttributes.length === 0 ) {
Expand All @@ -216,26 +218,24 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
( [ sourceName, { getFieldsList, usesContext } ] ) => {
if ( getFieldsList ) {
// Populate context.
const context = {};
if ( usesContext?.length ) {
for ( const key of usesContext ) {
context[ key ] = blockContext[ key ];
}
}
const sourceList = getFieldsList( {
_fieldsList[ sourceName ] = getFieldsList( {
select,
context,
} );
// Only add source if the list is not empty.
if ( Object.keys( sourceList || {} ).length ) {
_fieldsList[ sourceName ] = { ...sourceList };
}

// Clean `context` variable for next iterations.
Object.keys( context ).forEach( ( key ) => {
delete context[ key ];
} );
}
}
);
return (
Object.values( _fieldsList ).length > 0 && { ..._fieldsList }
);
return _fieldsList;
},
[ blockContext, bindableAttributes ]
);
Expand All @@ -255,6 +255,13 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
}
} );

// Remove empty sources from the list of fields.
Object.entries( fieldsList || {} ).forEach( ( [ key, value ] ) => {
if ( ! Object.keys( value || {} ).length ) {
delete fieldsList[ key ];
}
} );

// Lock the UI when the user can't update bindings or there are no fields to connect to.
const readOnly =
! canUpdateBlockBindings || ! Object.keys( fieldsList || {} ).length;
Expand Down
79 changes: 47 additions & 32 deletions packages/editor/src/bindings/post-meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* WordPress dependencies
*/
import { store as coreDataStore } from '@wordpress/core-data';
import { createSelector } from '@wordpress/data';

/**
* Internal dependencies
Expand Down Expand Up @@ -34,42 +35,56 @@ import { unlock } from '../lock-unlock';
* }
* ```
*/
function getPostMetaFields( select, context ) {
const { getEditedEntityRecord } = select( coreDataStore );
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );
const getPostMetaFields = createSelector(
( select, context ) => {
const { getEditedEntityRecord } = select( coreDataStore );
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );

let entityMetaValues;
// Try to get the current entity meta values.
if ( context?.postType && context?.postId ) {
entityMetaValues = getEditedEntityRecord(
'postType',
context?.postType,
context?.postId
).meta;
}

const registeredFields = getRegisteredPostMeta( context?.postType );
const metaFields = {};
Object.entries( registeredFields || {} ).forEach( ( [ key, props ] ) => {
// Don't include footnotes or private fields.
if ( key !== 'footnotes' && key.charAt( 0 ) !== '_' ) {
metaFields[ key ] = {
label: props.title || key,
value:
// When using the entity value, an empty string IS a valid value.
entityMetaValues?.[ key ] ??
// When using the default, an empty string IS NOT a valid value.
( props.default || undefined ),
};
let entityMetaValues;
// Try to get the current entity meta values.
if ( context?.postType && context?.postId ) {
entityMetaValues = getEditedEntityRecord(
'postType',
context?.postType,
context?.postId
).meta;
}
} );

if ( ! Object.keys( metaFields || {} ).length ) {
return null;
}
const registeredFields = getRegisteredPostMeta( context?.postType );
const metaFields = {};
Object.entries( registeredFields || {} ).forEach(
( [ key, props ] ) => {
// Don't include footnotes or private fields.
if ( key !== 'footnotes' && key.charAt( 0 ) !== '_' ) {
metaFields[ key ] = {
label: props.title || key,
value:
// When using the entity value, an empty string IS a valid value.
entityMetaValues?.[ key ] ??
// When using the default, an empty string IS NOT a valid value.
( props.default || undefined ),
};
}
}
);

return metaFields;
}
if ( ! Object.keys( metaFields || {} ).length ) {
return null;
}

return metaFields;
},
( select, context ) => [
select( coreDataStore ).getEditedEntityRecord(
'postType',
context.postType,
context.postId
).meta,
unlock( select( coreDataStore ) ).getRegisteredPostMeta(
context.postType
),
]
);

export default {
name: 'core/post-meta',
Expand Down

0 comments on commit e9e00d4

Please sign in to comment.