I’ve built a Featured Gallery component for Gutenberg that uses the withSelect
and withDispatch
higher order components to store the selected images in a meta field.
I’m wondering if this code can be converted to use the useSelect
and useDispatch
hooks instead to simplify it. Is it possible? I tried to do it myself reading the almost useless Gutenberg docs with no success.
Any help would be appreciated.
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
BaseControl,
Button
} = wp.components;
const { compose } = wp.compose;
const { withSelect, withDispatch } = wp.data;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
/**
* Internal dependencies
*/
import FeaturedGalleryImage from './featured-gallery-image';
const ALLOWED_MEDIA_TYPES = [ 'image' ];
function FeaturedGallery( {
featuredGalleryIds,
onUpdateGallery,
onClearGallery,
noticeUI,
} ) {
const instructions = (
<p>
{ __(
'To edit the featured gallery, you need permission to upload media.', 'my-featured-gallery'
) }
</p>
);
const hasImages = !! featuredGalleryIds.length;
return (
<BaseControl
className="my-featured-gallery"
>
{ noticeUI }
<div className="editor-post-featured-gallery">
<div className="editor-post-featured-gallery__container">
{ hasImages && (
<ul className="featured-gallery-grid">
{ featuredGalleryIds.map( ( img ) => (
<li key={ img } tabIndex={0}>
<FeaturedGalleryImage
id={ img }
/>
</li>
) ) }
</ul>
) }
</div>
<MediaUploadCheck fallback={ instructions }>
<MediaUpload
title={ __( 'Featured gallery', 'my-featured-gallery' ) }
multiple
gallery
addToGallery={ hasImages }
onSelect={ onUpdateGallery }
allowedTypes={ ALLOWED_MEDIA_TYPES }
value={ hasImages ? featuredGalleryIds : [] }
render={ ( { open } ) => (
<Button
className={
hasImages
? 'editor-post-featured-gallery__edit'
: 'editor-post-featured-gallery__add'
}
onClick={ open }
isSecondary
>
{
hasImages
? __( 'Edit gallery', 'my-featured-gallery' )
: __( 'Add to gallery', 'my-featured-gallery' )
}
</Button>
) }
/>
</MediaUploadCheck>
{ hasImages && (
<MediaUploadCheck>
<Button onClick={ onClearGallery } isLink isDestructive>
{
__( 'Clear gallery', 'my-featured-gallery' )
}
</Button>
</MediaUploadCheck>
) }
</div>
</BaseControl>
);
}
const applyWithSelect = withSelect( ( select ) => {
const { getPostType } = select( 'core' );
const { getCurrentPostId, getEditedPostAttribute } = select(
'core/editor'
);
const meta = getEditedPostAttribute( 'meta' );
const featuredGalleryIds = meta._featured_gallery;
return {
currentPostId: getCurrentPostId(),
postType: getPostType( getEditedPostAttribute( 'type' ) ),
featuredGalleryIds,
};
} );
const applyWithDispatch = withDispatch( ( dispatch ) => {
const { editPost } = dispatch( 'core/editor' );
return {
onUpdateGallery( images ) {
const items = images.map( ( item ) => item.id );
const meta = { _featured_gallery: items };
editPost( { meta } );
},
onClearGallery() {
const meta = { _featured_gallery: [] };
editPost( { meta } );
}
};
}
);
export default compose(
applyWithSelect,
applyWithDispatch,
)( FeaturedGallery );