You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress registerBlockType自定义块保存后预览数据未拉取问题

问题根本原因

古腾堡块的save方法最终输出的是静态HTML内容,不会在前端预览/公开页面中运行React组件的生命周期逻辑,你在save中引入的<PnImage/>组件只会在保存时执行一次静态渲染,此时没有运行componentDidMount、componentDidUpdate的环境,也拿不到pnRest的运行时对象,自然无法拉取图片数据,只能渲染出加载失败的提示文本。

最优解决方案:将图片数据存入块属性,保存时直接输出静态标签

这个方案的优势是前端页面加载更快、SEO友好,不需要额外加载前端脚本。

第一步:扩展块的属性配置

在registerBlockType的attributes中新增图片相关存储字段:

attributes: {
    pid: {
        type: "number",
        default: 8
    },
    // 新增图片存储字段
    imageUrl: {
        type: "string",
        default: ""
    },
    imageAlt: {
        type: "string",
        default: ""
    }
},

第二步:修改edit逻辑,拉取到图片后同步存入属性

修改edit方法,给<PnImage/>添加数据回调,拉取到图片数据后存入块属性:

edit: ( {attributes, setAttributes} ) => {
    console.log( "Edit", attributes )
    return (
        <p { ...useBlockProps() }>
             {"Editoor " + attributes.pid}
            <PnImage 
                pid={attributes.pid}
                // 新增回调,拉取到数据后存入属性
                onImageFetched={(imageData) => {
                    setAttributes({
                        imageUrl: imageData.URL,
                        imageAlt: imageData.alt || `图片-${attributes.pid}`
                    })
                }}
            />
            <NumberControl
                label="PID"
                isShiftStepEnabled={ true }
                onChange={ value => { setAttributes( {pid: value})} }
                shiftStep={ 10 }
                value={ attributes.pid }
            />
        </p>
    )
},

第三步:修改PnImage组件,拉取到数据后触发回调

在PnImage的Fetch方法中,拿到返回数据后调用传入的回调:

Fetch() { // fetch wrapper
    if (this.props.pid != this.state.pid && this.props.pid ) {
        console.log( "fetching: pid=", this.props.pid )
        pnRest.Fetch('image/get', { pid: this.props.pid, size: this.props.size })
            .then(data => {
                if ( data ) {       // image not found returns undefined
                    this.setState({ image: data, pid: data.id })
                    // 触发回调传递数据
                    this.props.onImageFetched?.(data)
                } else {
                    console.log( "Couldn't find image for pid " + this.props.pid )
                }
            });
    }
}

第四步:重写save方法,直接输出静态图片标签

不要在save中使用<PnImage/>组件,直接用已经存储的图片属性输出静态HTML:

save: ({ attributes }) => {
    return (
        <p { ...useBlockProps.save() }>
            { "Saved " + attributes.pid}
            {attributes.imageUrl && <img src={attributes.imageUrl} alt={attributes.imageAlt} />}
        </p>
    )
}

可选方案:前端动态渲染(仅适合需要实时更新图片的场景)

如果你确实需要前端页面每次加载时都实时拉取最新的图片数据,你需要额外做以下操作:

  • 将PnImage组件的代码打包为独立的前端JS脚本,在公开页面/预览页中入队加载
  • 给save方法输出的图片占位标签添加自定义标识,比如data-pid={attributes.pid}的自定义属性
  • 前端脚本加载完成后,遍历页面上的自定义标识标签,初始化PnImage组件替换占位标签即可。

内容的提问来源于stack exchange,提问作者Kim Aldis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:27:01