我为古腾堡构建了一个特色画廊组件,它使用withSelect
和withDispatch
将所选图像存储在元字段中的高阶组件。我想知道是否可以将此代码转换为使用useSelect
和useDispatch
而是钩子来简化它。有可能吗?我试着自己读那些几乎无用的古腾堡文件,但没有成功。任何帮助都将不胜感激。
/**
* 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 );
最合适的回答,由SO网友:leemon 整理而成
我的头撞了古腾堡的墙几个小时后,我想出了一个似乎有效的办法。它使用useSelect
和useEntityProp
钩子而不是withSelect
和withDispatch
HOCs。事实是,使用挂钩可以使代码更简单、更容易理解。
/**
* WordPress dependencies
*/
const { __ } = wp.i18n;
const {
BaseControl,
Button
} = wp.components;
const { useSelect } = wp.data;
const { useEntityProp } = wp.coreData;
const { MediaUpload, MediaUploadCheck } = wp.blockEditor;
/**
* Internal dependencies
*/
import FeaturedGalleryImage from \'./featured-gallery-image\';
const ALLOWED_MEDIA_TYPES = [ \'image\' ];
function FeaturedGallery( {
noticeUI,
} ) {
const instructions = (
<p>
{ __(
\'To edit the featured gallery, you need permission to upload media.\', \'my-featured-gallery\'
) }
</p>
);
const postType = useSelect(
( select ) => select( \'core/editor\' ).getCurrentPostType(),
[]
);
const [ meta, setMeta ] = useEntityProp(
\'postType\',
postType,
\'meta\'
);
const featuredGalleryIds = meta[\'_featured_gallery\'];
const hasImages = !! featuredGalleryIds.length;
function onUpdateGallery( images ) {
const items = images.map( ( item ) => item.id );
setMeta( { ...meta, \'_featured_gallery\': items } );
}
function onClearGallery() {
setMeta( { ...meta, \'_featured_gallery\': [] } );
}
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>
);
}
export default FeaturedGallery;