Wordpress Gutenberg Block:在 BlockEdit 过滤器 HOC 中使用 wp.data.select

问题描述

我试图通过拉入媒体描述字段并将其内容用作额外属性来扩展 core/image 块。我目前坚持在 BlockEdit 过滤器 HOC 中使用 wp.data.select('core').getMedia(id) 调用 Rest API 来工作。无论我到目前为止尝试过什么(“直接”使用 select 就像下面的示例代码useSelect 钩子一样,它总是导致相同的错误 "TypeError: select(...).getMedia(...) is undefined"。我成功地使用了核心块扩展用于其他功能以及其他自定义块中的许多不同选择调用。我正在从 select 包中导入 useSelectwp.data,并在插件 PHP 中设置了我的依赖项。>

这是我的代码(相关部分):

脚本顶部

const { select,useSelect } = wp.data;
const restrictTo = ['core/image'];

BlockEdit HOC – 包装图像块的编辑功能

const withDescription = createHigherOrderComponent((BlockEdit) => {
    return (props) => {
        const {name,attributes,setAttributes,isSelected} = props;
        if ( isSelected && restrictTo.includes(name) ) {
            const {id} = attributes;
            // id will be available when image is chosen from the inserter
            if (id) {
                /* doesn't work,yields error described above,even with useSelect hook */
                const desc = select('core').getMedia(id).description.raw;
            }
            // 
        }
        return (
            <Fragment>
                <BlockEdit {...props} />
                <Inspector Controls stuff...>
            </Fragment>
        )
    };
},'withDescription');

过滤器

addFilter('editor.BlockEdit','vortac/with-description',withDescription);

我已经搜索了涵盖类似问题的文章和帮助,并从 wordpress.org 支持论坛中找到了这个: https://wordpress.org/support/topic/how-to-use-wp-data-select-in-blocklist/

@jorgefilipecosta 引用了一段在 HOC 中实际使用 select 的核心代码。这是一个不同的 BlockFilter editor.BlockListBlock though,但我不认为这应该有所作为。

预先感谢您的帮助。

解决方法

我终于在我的代码中找到了错误。正如我在发布问题时假设的那样,在 select 过滤器 HOC 中使用 BlockEdit 并不是真正的问题。 select 形式的 const desc = select('core').getMedia(id).description.raw; 调用本身不正确。我想它不起作用,因为 select 调用产生了一个承诺,并且在为 .getMedia() 加载值之前,无法访问字段 description,导致我最初的错误在我的问题中描述。所以这是我最终实现中使用 useSelect 钩子(同样只是相关部分)的实际简单解决方案:

const { select,useSelect } = wp.data;
const restrictTo = [ 'core/image' ];
const withDescription = createHigherOrderComponent( ( BlockEdit ) => {
    return ( props ) => {
        const { name,attributes,setAttributes,isSelected } = props;
        if ( isSelected && restrictTo.includes( name ) ) {
            const { id } = attributes;
            
            // an image id will be available as soon as an image is chosen from the inserter
            if ( id ) {
                const tmpDesc = useSelect( ( select ) => {
                   return select( 'core' ).getMedia( id );
                },[ id ] );
                // if a value for tmpDesc is set its raw description will be accessible
                const desc = ( tmpDesc ) ? tmpDesc[ 'description' ][ 'raw' ] : '';
            }
            // 
        }
        return (
            <Fragment>
                <BlockEdit {...props} />
                <Inspector Controls stuff...>
            </Fragment>
        )
    };
},'withDescription');
addFilter('editor.BlockEdit','vortac/with-description',withDescription);