Skip to content

Conversation

@adamziel
Copy link
Contributor

@adamziel adamziel commented Feb 15, 2022

Description

This PR refactors the verbose usages of getEntityRecord and getEntityRecords like this:

const { menus, isResolvingMenus, hasResolvedMenus } = useSelect(
	( select ) => {
		const { getMenus, isResolving, hasFinishedResolution } = select(
			coreStore
		);

		const menusParameters = [ { per_page: -1, context: 'view' } ];

		return {
			menus: getMenus( ...menusParameters ),
			isResolvingMenus: isResolving( 'getMenus', menusParameters ),
			hasResolvedMenus: hasFinishedResolution(
				'getMenus',
				menusParameters
			),
		};
	},
	[]
);

Into more succinct ones like this:

const { records, isResolving, hasResolved } = useEntityRecords(
	'root',
	'menu',
	{ per_page: -1, context: 'view' }
);

Based on the new useEntityRecord and useEntityRecords hooks introduced starting at #38135

Test plan

Confirm all the tests are green

@github-actions
Copy link

github-actions bot commented Feb 15, 2022

Size Change: +2.3 kB (0%)

Total Size: 1.16 MB

Filename Size Change
build/block-editor/index.min.js 144 kB +4 B (0%)
build/block-library/index.min.js 168 kB +259 B (0%)
build/core-data/index.min.js 14 kB +19 B (0%)
build/data/index.min.js 8.03 kB +315 B (+4%)
build/edit-navigation/index.min.js 16.1 kB -50 B (0%)
build/edit-navigation/style-rtl.css 4.04 kB +282 B (+8%) 🔍
build/edit-navigation/style.css 4.05 kB +289 B (+8%) 🔍
build/edit-post/style-rtl.css 7.24 kB +98 B (+1%)
build/edit-post/style.css 7.24 kB +105 B (+1%)
build/edit-site/index.min.js 41.9 kB +76 B (0%)
build/edit-site/style-rtl.css 7.44 kB +204 B (+3%)
build/edit-site/style.css 7.42 kB +197 B (+3%)
build/edit-widgets/style-rtl.css 4.4 kB +273 B (+7%) 🔍
build/edit-widgets/style.css 4.39 kB +267 B (+6%) 🔍
build/editor/index.min.js 38.4 kB -68 B (0%)
build/widgets/index.min.js 7.21 kB +26 B (0%)
ℹ️ View Unchanged
Filename Size
build/a11y/index.min.js 993 B
build/admin-manifest/index.min.js 1.24 kB
build/annotations/index.min.js 2.77 kB
build/api-fetch/index.min.js 2.27 kB
build/autop/index.min.js 2.15 kB
build/blob/index.min.js 487 B
build/block-directory/index.min.js 6.49 kB
build/block-directory/style-rtl.css 1.01 kB
build/block-directory/style.css 1.01 kB
build/block-editor/default-editor-styles-rtl.css 378 B
build/block-editor/default-editor-styles.css 378 B
build/block-editor/style-rtl.css 14.8 kB
build/block-editor/style.css 14.8 kB
build/block-library/blocks/archives/editor-rtl.css 61 B
build/block-library/blocks/archives/editor.css 60 B
build/block-library/blocks/archives/style-rtl.css 65 B
build/block-library/blocks/archives/style.css 65 B
build/block-library/blocks/audio/editor-rtl.css 150 B
build/block-library/blocks/audio/editor.css 150 B
build/block-library/blocks/audio/style-rtl.css 111 B
build/block-library/blocks/audio/style.css 111 B
build/block-library/blocks/audio/theme-rtl.css 125 B
build/block-library/blocks/audio/theme.css 125 B
build/block-library/blocks/block/editor-rtl.css 161 B
build/block-library/blocks/block/editor.css 161 B
build/block-library/blocks/button/editor-rtl.css 445 B
build/block-library/blocks/button/editor.css 445 B
build/block-library/blocks/button/style-rtl.css 560 B
build/block-library/blocks/button/style.css 560 B
build/block-library/blocks/buttons/editor-rtl.css 292 B
build/block-library/blocks/buttons/editor.css 292 B
build/block-library/blocks/buttons/style-rtl.css 275 B
build/block-library/blocks/buttons/style.css 275 B
build/block-library/blocks/calendar/style-rtl.css 207 B
build/block-library/blocks/calendar/style.css 207 B
build/block-library/blocks/categories/editor-rtl.css 84 B
build/block-library/blocks/categories/editor.css 83 B
build/block-library/blocks/categories/style-rtl.css 79 B
build/block-library/blocks/categories/style.css 79 B
build/block-library/blocks/code/style-rtl.css 103 B
build/block-library/blocks/code/style.css 103 B
build/block-library/blocks/code/theme-rtl.css 124 B
build/block-library/blocks/code/theme.css 124 B
build/block-library/blocks/columns/editor-rtl.css 108 B
build/block-library/blocks/columns/editor.css 108 B
build/block-library/blocks/columns/style-rtl.css 406 B
build/block-library/blocks/columns/style.css 406 B
build/block-library/blocks/comment-author-avatar/editor-rtl.css 125 B
build/block-library/blocks/comment-author-avatar/editor.css 125 B
build/block-library/blocks/comment-template/style-rtl.css 127 B
build/block-library/blocks/comment-template/style.css 127 B
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css 123 B
build/block-library/blocks/comments-pagination-numbers/editor.css 121 B
build/block-library/blocks/comments-pagination/editor-rtl.css 222 B
build/block-library/blocks/comments-pagination/editor.css 209 B
build/block-library/blocks/comments-pagination/style-rtl.css 235 B
build/block-library/blocks/comments-pagination/style.css 231 B
build/block-library/blocks/comments-query-loop/editor-rtl.css 95 B
build/block-library/blocks/comments-query-loop/editor.css 95 B
build/block-library/blocks/cover/editor-rtl.css 546 B
build/block-library/blocks/cover/editor.css 547 B
build/block-library/blocks/cover/style-rtl.css 1.56 kB
build/block-library/blocks/cover/style.css 1.56 kB
build/block-library/blocks/embed/editor-rtl.css 293 B
build/block-library/blocks/embed/editor.css 293 B
build/block-library/blocks/embed/style-rtl.css 417 B
build/block-library/blocks/embed/style.css 417 B
build/block-library/blocks/embed/theme-rtl.css 124 B
build/block-library/blocks/embed/theme.css 124 B
build/block-library/blocks/file/editor-rtl.css 300 B
build/block-library/blocks/file/editor.css 300 B
build/block-library/blocks/file/style-rtl.css 255 B
build/block-library/blocks/file/style.css 255 B
build/block-library/blocks/file/view.min.js 353 B
build/block-library/blocks/freeform/editor-rtl.css 2.44 kB
build/block-library/blocks/freeform/editor.css 2.44 kB
build/block-library/blocks/gallery/editor-rtl.css 965 B
build/block-library/blocks/gallery/editor.css 967 B
build/block-library/blocks/gallery/style-rtl.css 1.61 kB
build/block-library/blocks/gallery/style.css 1.61 kB
build/block-library/blocks/gallery/theme-rtl.css 122 B
build/block-library/blocks/gallery/theme.css 122 B
build/block-library/blocks/group/editor-rtl.css 159 B
build/block-library/blocks/group/editor.css 159 B
build/block-library/blocks/group/style-rtl.css 57 B
build/block-library/blocks/group/style.css 57 B
build/block-library/blocks/group/theme-rtl.css 78 B
build/block-library/blocks/group/theme.css 78 B
build/block-library/blocks/heading/style-rtl.css 114 B
build/block-library/blocks/heading/style.css 114 B
build/block-library/blocks/html/editor-rtl.css 332 B
build/block-library/blocks/html/editor.css 333 B
build/block-library/blocks/image/editor-rtl.css 731 B
build/block-library/blocks/image/editor.css 730 B
build/block-library/blocks/image/style-rtl.css 518 B
build/block-library/blocks/image/style.css 523 B
build/block-library/blocks/image/theme-rtl.css 124 B
build/block-library/blocks/image/theme.css 124 B
build/block-library/blocks/latest-comments/style-rtl.css 284 B
build/block-library/blocks/latest-comments/style.css 284 B
build/block-library/blocks/latest-posts/editor-rtl.css 199 B
build/block-library/blocks/latest-posts/editor.css 198 B
build/block-library/blocks/latest-posts/style-rtl.css 447 B
build/block-library/blocks/latest-posts/style.css 446 B
build/block-library/blocks/list/style-rtl.css 94 B
build/block-library/blocks/list/style.css 94 B
build/block-library/blocks/media-text/editor-rtl.css 266 B
build/block-library/blocks/media-text/editor.css 263 B
build/block-library/blocks/media-text/style-rtl.css 493 B
build/block-library/blocks/media-text/style.css 490 B
build/block-library/blocks/more/editor-rtl.css 431 B
build/block-library/blocks/more/editor.css 431 B
build/block-library/blocks/navigation-link/editor-rtl.css 649 B
build/block-library/blocks/navigation-link/editor.css 650 B
build/block-library/blocks/navigation-link/style-rtl.css 94 B
build/block-library/blocks/navigation-link/style.css 94 B
build/block-library/blocks/navigation-submenu/editor-rtl.css 299 B
build/block-library/blocks/navigation-submenu/editor.css 299 B
build/block-library/blocks/navigation-submenu/view.min.js 375 B
build/block-library/blocks/navigation/editor-rtl.css 2.03 kB
build/block-library/blocks/navigation/editor.css 2.04 kB
build/block-library/blocks/navigation/style-rtl.css 1.89 kB
build/block-library/blocks/navigation/style.css 1.88 kB
build/block-library/blocks/navigation/view.min.js 2.85 kB
build/block-library/blocks/nextpage/editor-rtl.css 395 B
build/block-library/blocks/nextpage/editor.css 395 B
build/block-library/blocks/page-list/editor-rtl.css 363 B
build/block-library/blocks/page-list/editor.css 363 B
build/block-library/blocks/page-list/style-rtl.css 175 B
build/block-library/blocks/page-list/style.css 175 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B
build/block-library/blocks/paragraph/editor.css 157 B
build/block-library/blocks/paragraph/style-rtl.css 273 B
build/block-library/blocks/paragraph/style.css 273 B
build/block-library/blocks/post-author/style-rtl.css 175 B
build/block-library/blocks/post-author/style.css 176 B
build/block-library/blocks/post-comments-form/style-rtl.css 446 B
build/block-library/blocks/post-comments-form/style.css 446 B
build/block-library/blocks/post-comments/style-rtl.css 521 B
build/block-library/blocks/post-comments/style.css 521 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B
build/block-library/blocks/post-excerpt/editor.css 73 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B
build/block-library/blocks/post-excerpt/style.css 69 B
build/block-library/blocks/post-featured-image/editor-rtl.css 721 B
build/block-library/blocks/post-featured-image/editor.css 721 B
build/block-library/blocks/post-featured-image/style-rtl.css 153 B
build/block-library/blocks/post-featured-image/style.css 153 B
build/block-library/blocks/post-template/editor-rtl.css 99 B
build/block-library/blocks/post-template/editor.css 98 B
build/block-library/blocks/post-template/style-rtl.css 323 B
build/block-library/blocks/post-template/style.css 323 B
build/block-library/blocks/post-terms/style-rtl.css 73 B
build/block-library/blocks/post-terms/style.css 73 B
build/block-library/blocks/post-title/style-rtl.css 80 B
build/block-library/blocks/post-title/style.css 80 B
build/block-library/blocks/preformatted/style-rtl.css 103 B
build/block-library/blocks/preformatted/style.css 103 B
build/block-library/blocks/pullquote/editor-rtl.css 198 B
build/block-library/blocks/pullquote/editor.css 198 B
build/block-library/blocks/pullquote/style-rtl.css 389 B
build/block-library/blocks/pullquote/style.css 388 B
build/block-library/blocks/pullquote/theme-rtl.css 167 B
build/block-library/blocks/pullquote/theme.css 167 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B
build/block-library/blocks/query-pagination/editor-rtl.css 221 B
build/block-library/blocks/query-pagination/editor.css 211 B
build/block-library/blocks/query-pagination/style-rtl.css 234 B
build/block-library/blocks/query-pagination/style.css 231 B
build/block-library/blocks/query/editor-rtl.css 131 B
build/block-library/blocks/query/editor.css 132 B
build/block-library/blocks/quote/style-rtl.css 201 B
build/block-library/blocks/quote/style.css 201 B
build/block-library/blocks/quote/theme-rtl.css 223 B
build/block-library/blocks/quote/theme.css 226 B
build/block-library/blocks/read-more/style-rtl.css 132 B
build/block-library/blocks/read-more/style.css 132 B
build/block-library/blocks/rss/editor-rtl.css 202 B
build/block-library/blocks/rss/editor.css 204 B
build/block-library/blocks/rss/style-rtl.css 289 B
build/block-library/blocks/rss/style.css 288 B
build/block-library/blocks/search/editor-rtl.css 165 B
build/block-library/blocks/search/editor.css 165 B
build/block-library/blocks/search/style-rtl.css 397 B
build/block-library/blocks/search/style.css 398 B
build/block-library/blocks/search/theme-rtl.css 64 B
build/block-library/blocks/search/theme.css 64 B
build/block-library/blocks/separator/editor-rtl.css 99 B
build/block-library/blocks/separator/editor.css 99 B
build/block-library/blocks/separator/style-rtl.css 233 B
build/block-library/blocks/separator/style.css 233 B
build/block-library/blocks/separator/theme-rtl.css 172 B
build/block-library/blocks/separator/theme.css 172 B
build/block-library/blocks/shortcode/editor-rtl.css 474 B
build/block-library/blocks/shortcode/editor.css 474 B
build/block-library/blocks/site-logo/editor-rtl.css 744 B
build/block-library/blocks/site-logo/editor.css 744 B
build/block-library/blocks/site-logo/style-rtl.css 181 B
build/block-library/blocks/site-logo/style.css 181 B
build/block-library/blocks/site-tagline/editor-rtl.css 86 B
build/block-library/blocks/site-tagline/editor.css 86 B
build/block-library/blocks/site-title/editor-rtl.css 84 B
build/block-library/blocks/site-title/editor.css 84 B
build/block-library/blocks/social-link/editor-rtl.css 177 B
build/block-library/blocks/social-link/editor.css 177 B
build/block-library/blocks/social-links/editor-rtl.css 674 B
build/block-library/blocks/social-links/editor.css 673 B
build/block-library/blocks/social-links/style-rtl.css 1.37 kB
build/block-library/blocks/social-links/style.css 1.36 kB
build/block-library/blocks/spacer/editor-rtl.css 332 B
build/block-library/blocks/spacer/editor.css 332 B
build/block-library/blocks/spacer/style-rtl.css 48 B
build/block-library/blocks/spacer/style.css 48 B
build/block-library/blocks/table/editor-rtl.css 471 B
build/block-library/blocks/table/editor.css 472 B
build/block-library/blocks/table/style-rtl.css 481 B
build/block-library/blocks/table/style.css 481 B
build/block-library/blocks/table/theme-rtl.css 188 B
build/block-library/blocks/table/theme.css 188 B
build/block-library/blocks/tag-cloud/style-rtl.css 226 B
build/block-library/blocks/tag-cloud/style.css 227 B
build/block-library/blocks/template-part/editor-rtl.css 235 B
build/block-library/blocks/template-part/editor.css 235 B
build/block-library/blocks/template-part/theme-rtl.css 101 B
build/block-library/blocks/template-part/theme.css 101 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B
build/block-library/blocks/text-columns/editor.css 95 B
build/block-library/blocks/text-columns/style-rtl.css 166 B
build/block-library/blocks/text-columns/style.css 166 B
build/block-library/blocks/verse/style-rtl.css 87 B
build/block-library/blocks/verse/style.css 87 B
build/block-library/blocks/video/editor-rtl.css 571 B
build/block-library/blocks/video/editor.css 572 B
build/block-library/blocks/video/style-rtl.css 173 B
build/block-library/blocks/video/style.css 173 B
build/block-library/blocks/video/theme-rtl.css 124 B
build/block-library/blocks/video/theme.css 124 B
build/block-library/common-rtl.css 934 B
build/block-library/common.css 932 B
build/block-library/editor-rtl.css 9.92 kB
build/block-library/editor.css 9.92 kB
build/block-library/reset-rtl.css 474 B
build/block-library/reset.css 474 B
build/block-library/style-rtl.css 11.4 kB
build/block-library/style.css 11.4 kB
build/block-library/theme-rtl.css 665 B
build/block-library/theme.css 670 B
build/block-serialization-default-parser/index.min.js 1.12 kB
build/block-serialization-spec-parser/index.min.js 2.83 kB
build/blocks/index.min.js 46.4 kB
build/components/index.min.js 217 kB
build/components/style-rtl.css 15.6 kB
build/components/style.css 15.6 kB
build/compose/index.min.js 11.2 kB
build/customize-widgets/index.min.js 11.2 kB
build/customize-widgets/style-rtl.css 1.39 kB
build/customize-widgets/style.css 1.39 kB
build/data-controls/index.min.js 663 B
build/date/index.min.js 31.9 kB
build/deprecated/index.min.js 518 B
build/dom-ready/index.min.js 336 B
build/dom/index.min.js 4.53 kB
build/edit-post/classic-rtl.css 546 B
build/edit-post/classic.css 547 B
build/edit-post/index.min.js 29.9 kB
build/edit-widgets/index.min.js 16.5 kB
build/editor/style-rtl.css 3.71 kB
build/editor/style.css 3.71 kB
build/element/index.min.js 4.29 kB
build/escape-html/index.min.js 548 B
build/format-library/index.min.js 6.62 kB
build/format-library/style-rtl.css 571 B
build/format-library/style.css 571 B
build/hooks/index.min.js 1.66 kB
build/html-entities/index.min.js 454 B
build/i18n/index.min.js 3.79 kB
build/is-shallow-equal/index.min.js 535 B
build/keyboard-shortcuts/index.min.js 1.83 kB
build/keycodes/index.min.js 1.41 kB
build/list-reusable-blocks/index.min.js 1.75 kB
build/list-reusable-blocks/style-rtl.css 838 B
build/list-reusable-blocks/style.css 838 B
build/media-utils/index.min.js 2.94 kB
build/notices/index.min.js 957 B
build/nux/index.min.js 2.12 kB
build/nux/style-rtl.css 751 B
build/nux/style.css 749 B
build/plugins/index.min.js 1.98 kB
build/preferences/index.min.js 1.2 kB
build/primitives/index.min.js 949 B
build/priority-queue/index.min.js 611 B
build/react-i18n/index.min.js 704 B
build/react-refresh-entry/index.min.js 8.44 kB
build/react-refresh-runtime/index.min.js 7.31 kB
build/redux-routine/index.min.js 2.69 kB
build/reusable-blocks/index.min.js 2.24 kB
build/reusable-blocks/style-rtl.css 256 B
build/reusable-blocks/style.css 256 B
build/rich-text/index.min.js 11.1 kB
build/server-side-render/index.min.js 1.61 kB
build/shortcode/index.min.js 1.52 kB
build/token-list/index.min.js 668 B
build/url/index.min.js 1.94 kB
build/viewport/index.min.js 1.08 kB
build/warning/index.min.js 280 B
build/widgets/style-rtl.css 1.16 kB
build/widgets/style.css 1.16 kB
build/wordcount/index.min.js 1.07 kB

compressed-size-action

@gziolo gziolo added the [Type] Code Quality Issues or PRs that relate to code quality label Feb 15, 2022
@adamziel
Copy link
Contributor Author

@gziolo I wonder what to do with usages like this one:

const rawNavigationMenu = ref
? getEntityRecord( ...navigationMenuSingleArgs )
: null;

Where getEntityRecord is conditional. I see the following solutions:

  • Restore the runIf option
  • Skip the resolution if the ID argument is null – but this will close the door to accepting a contextual ID from EntityProvider
  • Don't refactor cases like that – but they're the most verbose ones

I'm curious about your thoughts here

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage of useEntityRecord looks great. We need to measure performance implications for useEntityRecords because we pass a new object instance on every component's re-render. I left a note next to the usage in code.

I really like how more predictable code becomes in addition to the less line of code. Developers should also benefit from TypeScript support when using IDEs. I like the direction very much 😄

const { categories, isResolving } = useEntityRecords(
'taxonomy',
'category',
query
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking here. On every re-render, we will have a different query object here, but it shouldn't matter because @wordpress/core-date picks data based on the standardised key computed from the query, right? I guess what I mean here is that before useSelect would get executed only when showOnlyTopLevel changes or when the store triggers an update. However, with the new implementation, it has to run useEntityRecords every time we pass a new query object.

I believe the same concern applies to every usage of useEntityRecords where query is dynamically computed which is all cases in this PR. We should check if there are any performance implications here.

Copy link
Contributor Author

@adamziel adamziel Mar 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gziolo AFAIR deps are tested for shallow equality, so it doesn't matter as long as there are no nested objects such as { _fields: [ 'id' ] }. In such a case, it would re-run the select callback, which then will return the exact same data. Edit: I think I got that wrong.

This may or may not have performance implications, depending on the specifics. I'd like to make sure this just never re-runs. I have two ideas:

  1. Add useMemo() in all such places
  2. Don't include queryArgs in deps and instead, rely on JSON.stringify( queryArgs ) – this removes the need to remember about useMemo() and should still be fast.

cc @kevin940726

Copy link
Contributor Author

@adamziel adamziel Mar 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of trying to guess whether the query has changed or not, I removed it as a dependency and added an additional deps argument instead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend not introducing new APIs with custom dependencies array, as suggested by the React team (with that in mind, we should probably refactor useQuerySelect at some point):

Generally saying, we recommend most custom Hooks to not use the dependencies argument, and instead provide a higher-level API that is more focused around a specific use case.

Serializing the query into a stabilized key is a possible solution. I believe getEntityRecords has already done that internally as @gziolo mentioned. We could do similar things here, maybe implicitly in useQuerySelect? I think this is how react-query does it too, but they leave this option to the users to provide their own stabilized key for each query.

@gziolo
Copy link
Member

gziolo commented Feb 18, 2022

const rawNavigationMenu = ref
? getEntityRecord( ...navigationMenuSingleArgs )
: null;

Where getEntityRecord is conditional. I see the following solutions:

  • Restore the runIf option
  • Skip the resolution if the ID argument is null – but this will close the door to accepting a contextual ID from EntityProvider
  • Don't refactor cases like that – but they're the most verbose ones

I would love to see this hook refactored first in a way where we branch code when ref is null and return early. I have a feeling that the current implementation doesn't share much logic anyway. The only API call that runs in both cases is:

const navigationMenuMultipleArgs = [
'postType',
'wp_navigation',
{ per_page: -1, status: 'publish' },
];
const navigationMenus = getEntityRecords(
...navigationMenuMultipleArgs
);

Maybe it's not worth the effort trying to use those new hooks in this place. In general, the rules of hooks and conditional code execution doesn't play along well 😞

  • Skip the resolution if the ID argument is null – but this will close the door to accepting a contextual ID from EntityProvider

That's a good reason to postpone the decision for now and revisit when you have some examples where this pattern is exercised.

@gziolo gziolo added the [Status] In Progress Tracking issues with work in progress label Feb 21, 2022
@gziolo gziolo mentioned this pull request Feb 24, 2022
@adamziel adamziel force-pushed the refactor/use-entity-hooks branch from 1d98151 to 77e854a Compare March 2, 2022 15:34
@adamziel adamziel force-pushed the refactor/use-entity-hooks branch from 0122560 to 7549861 Compare March 4, 2022 16:09
@adamziel
Copy link
Contributor Author

adamziel commented Mar 4, 2022

All the tests pass, yay! cc @gziolo; I still need to write the PR description, but let's not block reviewing on that

@gziolo
Copy link
Member

gziolo commented Mar 7, 2022

I just wanted to share a quick observation before I take a deeper dive into the code changes proposed. I see useEntityRecords used 9 times and useEntityRecord used 2 times. They use only 3 fields that those hooks return:

  • record/records
  • hasResolved
  • isResolving

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left my feedback. Is there any work left? This PR seems to be in very good shape.

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy about the current state of PR. I would encourage you to wait for some confirmation from folks familiar with the Navigation and Widget blocks before you move forward with this PR.

@adamziel
Copy link
Contributor Author

adamziel commented Mar 7, 2022

Luckily, I worked on both :-) But of course this would still greatly benefit from more eyes, cc @noisysocks @talldan @draganescu @getdave

Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good from a Navigation POV.

Nit: although more verbose and time consuming it might have been easier to break this up into smaller PRs allowing them to be reviewed merged incrementally.

Great work though - this new API makes this kind of thing a lot more readable.

Copy link
Contributor

@getdave getdave left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where getEntityRecord is conditional. I see the following solutions:

I wonder could we modify the API to allow for something like this:

const isImmediate = false;

const {
    execute: fetchMenuItems,
    records: menuItems 
    isResolving, 
    hasResolved
} = getMenuItems( ...menuItemsParameters,  isImmediate);


useEffect(()=> {
    if(hasSelectedMenu) {
        fetchMenuItems();
    }
},[hasSelectedMenu, fetchMenuItems ])

return {
        menuItems: menuItems,
        hasResolvedMenuItems: hasResolved,
};

I would make execute() an optional API which you could consume as required for edge cases such as this. It would be the responsibility of the consumer to invoke it to trigger the resolution.

Passing false to the hook defers the resolution of the selector until execute is called. We would make this true by default thereby meaning the 80% use case would still have the API you've already designed.

Also noting this would require some perf checks to ensure that fetchMenuItems is wrapped to ensure a consistent reference.

@noisysocks
Copy link
Member

The Legacy Widget block changes lgtm 👍

@kevin940726
Copy link
Member

Where getEntityRecord is conditional

react-query has this pattern of using enabled to skip/pause a query. Maybe we can do something similar.

const { records, isResolving, hasResolved } = useEntityRecords(
	'root',
	'menu',
	{ per_page: -1, context: 'view' },
	{ enabled: shouldEnabled }
);

Or maybe we can refactor useQuerySelect to something more verbose and make it a public/low-level API like:

useEntityRecords('root', 'menu', { per_page: -1, context: 'view' });

// is essentially the same as...

useQuerySelect((query) => {
  return query(coreStore).selectAll('root', 'menu', { per_page: -1, context: 'view' });
});

// So that skipping/pausing a query is as trivial as...

useQuerySelect((query) => {
  if (enabled) {
    return query(coreStore).selectAll('root', 'menu', { per_page: -1, context: 'view' });
  }
});

Not sure how possible the second solution is, but it could solve a lot of the issues with hooks at the same time (conditional, loops, infinite loading, etc).

@adamziel
Copy link
Contributor Author

adamziel commented Mar 8, 2022

The discussion seems to be mostly about the conditional execution – let's keep it going separately, and I'll go ahead and merge this PR.

@adamziel adamziel merged commit e4baab9 into trunk Mar 8, 2022
@adamziel adamziel deleted the refactor/use-entity-hooks branch March 8, 2022 14:01
@github-actions github-actions bot added this to the Gutenberg 12.8 milestone Mar 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Status] In Progress Tracking issues with work in progress [Type] Code Quality Issues or PRs that relate to code quality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants