Categories
WordPress

Gutenberg Snippet: Retrieve taxonomy terms with compose, withSelect, and getEntityRecords

A snippet that I need to remember.

No time to write any more about this now – I just want to get this distilled pattern in one place for later reference. It is for retrieving data from WordPress via APIs from the WordPress data package, and then using the data in a component. There are some functional programming concepts at play here that I am excited to learn, but not comfortable with nor aware of at the moment.

It is possible to do the below via apiFetch and async/await functions, but from what I understand at the moment, retrieving data via the WordPress data package i.e. the Redux store, is a more “official” and ultimately less complex way to it for WordPress’ core data types. Well, less complex after you understand how to do it in the first place which is no small feat in my opinion.

import { compose } from '@wordpress/compose';
import { withSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import {
    SelectControl,
    Spinner
} from '@wordpress/components';

// This is the component markup.
// The parameters must match what is returned from
// calls to withSelect and withDispatch in the
// compose method below.
const Render = ( { terms } ) => {

    if ( null === terms ) return <Spinner />;

    const termOptions = terms.map( ( term ) => {
        return {
            label: term.name,
            value: term.id
        }
    });

    return (
        <SelectControl
            label={ __(
                'Terms',
                'pmc-gutenberg'
            ) }
            value={ 2 }
            onChange={ ( value ) => console.log( value ) }
            options={ termOptions }
        />
    );
};

// This is the "actual" component, 
// together with the markup and data.
// You can add withDispatch as another argument 
// to the compose function and return an object 
// of methods to access in Render.
const TermsSelect = compose(
    withSelect( ( scopedSelect ) => {
        const {
            getEntityRecords
        } = scopedSelect( 'core' );

        return {
            terms: getEntityRecords( 'taxonomy', 'category', { per_page: 100 } ),
        };
    } )
)( Render );

// Export this component to use as JSX elsewhere 
// i.e. <TermsSelect />
export default TermsSelect;