Skip to content

Commit e9e00d4

Browse files
Try: Use createSelector
1 parent 8b494c6 commit e9e00d4

File tree

2 files changed

+63
-41
lines changed

2 files changed

+63
-41
lines changed

packages/block-editor/src/hooks/block-bindings.js

+16-9
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
205205
* whenever there are updates in block context.
206206
* `source.getFieldsList` may also call a selector via `registry.select`.
207207
*/
208+
// A constant object needs to be used to avoid unnecessary re-renders.
209+
const context = {};
208210
const fieldsList = useSelect(
209211
( select ) => {
210212
if ( ! bindableAttributes || bindableAttributes.length === 0 ) {
@@ -216,26 +218,24 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
216218
( [ sourceName, { getFieldsList, usesContext } ] ) => {
217219
if ( getFieldsList ) {
218220
// Populate context.
219-
const context = {};
220221
if ( usesContext?.length ) {
221222
for ( const key of usesContext ) {
222223
context[ key ] = blockContext[ key ];
223224
}
224225
}
225-
const sourceList = getFieldsList( {
226+
_fieldsList[ sourceName ] = getFieldsList( {
226227
select,
227228
context,
228229
} );
229-
// Only add source if the list is not empty.
230-
if ( Object.keys( sourceList || {} ).length ) {
231-
_fieldsList[ sourceName ] = { ...sourceList };
232-
}
230+
231+
// Clean `context` variable for next iterations.
232+
Object.keys( context ).forEach( ( key ) => {
233+
delete context[ key ];
234+
} );
233235
}
234236
}
235237
);
236-
return (
237-
Object.values( _fieldsList ).length > 0 && { ..._fieldsList }
238-
);
238+
return _fieldsList;
239239
},
240240
[ blockContext, bindableAttributes ]
241241
);
@@ -255,6 +255,13 @@ export const BlockBindingsPanel = ( { name: blockName, metadata } ) => {
255255
}
256256
} );
257257

258+
// Remove empty sources from the list of fields.
259+
Object.entries( fieldsList || {} ).forEach( ( [ key, value ] ) => {
260+
if ( ! Object.keys( value || {} ).length ) {
261+
delete fieldsList[ key ];
262+
}
263+
} );
264+
258265
// Lock the UI when the user can't update bindings or there are no fields to connect to.
259266
const readOnly =
260267
! canUpdateBlockBindings || ! Object.keys( fieldsList || {} ).length;

packages/editor/src/bindings/post-meta.js

+47-32
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* WordPress dependencies
33
*/
44
import { store as coreDataStore } from '@wordpress/core-data';
5+
import { createSelector } from '@wordpress/data';
56

67
/**
78
* Internal dependencies
@@ -34,42 +35,56 @@ import { unlock } from '../lock-unlock';
3435
* }
3536
* ```
3637
*/
37-
function getPostMetaFields( select, context ) {
38-
const { getEditedEntityRecord } = select( coreDataStore );
39-
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );
38+
const getPostMetaFields = createSelector(
39+
( select, context ) => {
40+
const { getEditedEntityRecord } = select( coreDataStore );
41+
const { getRegisteredPostMeta } = unlock( select( coreDataStore ) );
4042

41-
let entityMetaValues;
42-
// Try to get the current entity meta values.
43-
if ( context?.postType && context?.postId ) {
44-
entityMetaValues = getEditedEntityRecord(
45-
'postType',
46-
context?.postType,
47-
context?.postId
48-
).meta;
49-
}
50-
51-
const registeredFields = getRegisteredPostMeta( context?.postType );
52-
const metaFields = {};
53-
Object.entries( registeredFields || {} ).forEach( ( [ key, props ] ) => {
54-
// Don't include footnotes or private fields.
55-
if ( key !== 'footnotes' && key.charAt( 0 ) !== '_' ) {
56-
metaFields[ key ] = {
57-
label: props.title || key,
58-
value:
59-
// When using the entity value, an empty string IS a valid value.
60-
entityMetaValues?.[ key ] ??
61-
// When using the default, an empty string IS NOT a valid value.
62-
( props.default || undefined ),
63-
};
43+
let entityMetaValues;
44+
// Try to get the current entity meta values.
45+
if ( context?.postType && context?.postId ) {
46+
entityMetaValues = getEditedEntityRecord(
47+
'postType',
48+
context?.postType,
49+
context?.postId
50+
).meta;
6451
}
65-
} );
6652

67-
if ( ! Object.keys( metaFields || {} ).length ) {
68-
return null;
69-
}
53+
const registeredFields = getRegisteredPostMeta( context?.postType );
54+
const metaFields = {};
55+
Object.entries( registeredFields || {} ).forEach(
56+
( [ key, props ] ) => {
57+
// Don't include footnotes or private fields.
58+
if ( key !== 'footnotes' && key.charAt( 0 ) !== '_' ) {
59+
metaFields[ key ] = {
60+
label: props.title || key,
61+
value:
62+
// When using the entity value, an empty string IS a valid value.
63+
entityMetaValues?.[ key ] ??
64+
// When using the default, an empty string IS NOT a valid value.
65+
( props.default || undefined ),
66+
};
67+
}
68+
}
69+
);
7070

71-
return metaFields;
72-
}
71+
if ( ! Object.keys( metaFields || {} ).length ) {
72+
return null;
73+
}
74+
75+
return metaFields;
76+
},
77+
( select, context ) => [
78+
select( coreDataStore ).getEditedEntityRecord(
79+
'postType',
80+
context.postType,
81+
context.postId
82+
).meta,
83+
unlock( select( coreDataStore ) ).getRegisteredPostMeta(
84+
context.postType
85+
),
86+
]
87+
);
7388

7489
export default {
7590
name: 'core/post-meta',

0 commit comments

Comments
 (0)