What’s the difference between useSelect and useEntityRecords?

Now that I worked through the tutorial on useEntityRecords I was wondering:
What’s the difference in approach between this

 export default function Edit() { 
   const data = useEntityRecords( 'postType', 'page', { per_page: 20 } ); 
   return ( 
     <div {...useBlockProps() }> 
       <PagesList hasResolved={ data.loading } pages={ data.records } />     
     </div> ); } 

and this code Snippet:

 
 const data = useSelect(
    select => {
      return {
        pages: select( coreDataStore ).getEntityRecords( 'postType', 'page', { per_page: 20 } ),
        hasResolved: select( coreDataStore ).hasFinishedResolution( 'getEntityRecords', ['postType', 'page', { per_page: 20 } ] )
      }
    },
    []
  );

  return <PagesList hasResolved={ data.hasResolved } pages={ data.pages } />;
}

Answer:

The main difference in approach between the two code snippets lies in the way they retrieve data from the WordPress data store.

In the first code snippet:

export default function Edit() {
  const data = useEntityRecords( 'postType', 'page', { per_page: 20 } );

  return (
    <div {...useBlockProps() }>
      <PagesList hasResolved={ data.loading } pages={ data.records } />
    </div>
  );
}

The useEntityRecords hook is used directly to fetch the records of pages. The data object returned by the hook contains a loading property that indicates whether the data fetching is in progress, and a records property that holds the fetched pages.

The fetched data is then passed to the PagesList component as props: hasResolved is set to data.loading, and pages is set to data.records. The useBlockProps hook is used to apply certain block properties to the surrounding <div> element.

In the second code snippet:

export default function Edit() {
  const data = useSelect(
    select => {
      return {
        pages: select( coreDataStore ).getEntityRecords( 'postType', 'page', { per_page: 20 } ),
        hasResolved: select( coreDataStore ).hasFinishedResolution( 'getEntityRecords', ['postType', 'page', { per_page: 20 } ] )
      }
    },
    []
  );

  return <PagesList hasResolved={ data.hasResolved } pages={ data.pages } />;
}

The useSelect hook is used to fetch the pages from the WordPress data store. It receives a selector function that specifies the data to be retrieved. The selector function is provided with the select argument, which allows us to access and manipulate the WordPress data store. The fetched pages are obtained using select( coreDataStore ).getEntityRecords, and the hasResolved value is determined using select( coreDataStore ).hasFinishedResolution.

The fetched pages and hasResolved values are then passed to the PagesList component as props.

In summary, the first code snippet directly uses the useEntityRecords hook to fetch data, while the second code snippet uses the useSelect hook with a selector function to retrieve the data. The end result is similar, but the approach and underlying mechanism used to fetch the data differ.

And the last question: Why would I choose one approach over the other?

The choice between using useEntityRecords and useSelect depends on the specific requirements and flexibility needed in your code.

Here are some considerations to help you decide which approach to use:

  1. Simplicity: If you simply need to fetch entity records without complex data manipulation or additional resolution checks, useEntityRecords provides a straightforward way to retrieve data. It requires less code and may be easier to understand for simpler data fetching scenarios.
  2. Customization and Data Manipulation: If you need to perform additional data manipulation or require more control over the fetching process, useSelect offers more flexibility. With the selector function provided to useSelect, you can access the select argument to perform custom logic, combine multiple data sources, or transform the fetched data as needed.
  3. Resolution Checks: If you need to check if the data fetching has resolved or if you want to monitor the loading status of the data, useSelect allows you to use hasFinishedResolution to determine if the data is fully loaded. useEntityRecords does not provide a built-in way to check the resolution status.
  4. Extensibility: If you anticipate the need to fetch data from multiple data sources or different stores, useSelect allows you to access multiple data selectors within a single hook call. This can be useful if you need to fetch data from different parts of the WordPress data store or other custom data sources.

In general, if you have simple data fetching requirements and don’t need additional customization or resolution checks, useEntityRecords can be a straightforward choice. On the other hand, if you require more control over the data fetching process, need custom data manipulation, or want to monitor the resolution status, useSelect provides more flexibility and extensibility.


Comments

One response to “What’s the difference between useSelect and useEntityRecords?”

  1. I suspect this happened after posting, but I believe that useEntityRecords now supports isResolving and hasResolved. This WordPress Developer article is useful and cites those properties in the object returned by useEntityRecords: https://developer.wordpress.org/news/2023/05/19/useentityrecords-an-easier-way-to-fetch-wordpress-data/

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.