使用useSelect/useDispatch而不是With Select/With Dispatch

时间:2021-01-29 作者:leemon

我为古腾堡构建了一个特色画廊组件,它使用withSelectwithDispatch 将所选图像存储在元字段中的高阶组件。我想知道是否可以将此代码转换为使用useSelectuseDispatch 而是钩子来简化它。有可能吗?我试着自己读那些几乎无用的古腾堡文件,但没有成功。任何帮助都将不胜感激。

/**
 * 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 );

1 个回复
最合适的回答,由SO网友:leemon 整理而成

我的头撞了古腾堡的墙几个小时后,我想出了一个似乎有效的办法。它使用useSelectuseEntityProp 钩子而不是withSelectwithDispatch 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;

相关推荐

多国语言上的Gutenberg块JavaScript本地化不起作用

我可以使用wordpress成功翻译我的插件。org用于所有php字符串。一切都很好。我甚至可以看到需要翻译的字符串https://translate.wordpress.org/projects/wp-plugins/simpletoc/stable/de/default/ 在这种情况下,它是“更新目录”:https://plugins.trac.wordpress.org/browser/simpletoc/tags/1.8/build/index.js#L111所以我翻译了它们,等了24小时。我可以