EP218. “拆分 edit.js 文件与 useBlockProps 选中态”
🔒 登录后可标记已读把 Footer Block 的编辑器占位内容补齐(跟旧版本视觉一致),顺便建立这套现代做法接下来会反复用到的两个习惯:① 把 edit 函数拆到独立的 edit.js 文件,index.js 只负责导入拼装,方便以后编辑器 JSX 变复杂时保持整洁;② 用 useBlockProps() 补上 Block 的「选中态」外壳——这是用了 apiVersion: 3 之后必须手动接管的部分(Block Theme 章节 EP154 学过同样的坑,只是这次是在多 Block 现代化工作流里再次遇到)。之后照着同一套流程,把 Header、Events and Blogs 两个占位 Block 也迁移完成,删除旧文件收尾。
涉及文件
wp-content/themes/fictional-clean-blocks/src/footer/index.js(修改)wp-content/themes/fictional-clean-blocks/src/footer/edit.js(新建)wp-content/themes/fictional-clean-blocks/src/header/整套(新建,复制footer/文件夹改内容)wp-content/themes/fictional-clean-blocks/src/eventsandblogs/整套(新建,复制footer/文件夹改内容)wp-content/themes/fictional-clean-blocks/functions.php(修改,header/eventsandblogs也切换成register_block_type_from_metadata)- 删除
our-blocks/footer.js/footer.php、header.js/header.php、eventsandblogs.js/eventsandblogs.php(旧写法文件,迁移完成后清理)
代码实现
src/footer/edit.js(新建,从 index.js 拆分出来,并用 useBlockProps() 补上选中态外壳):
import { useBlockProps } from "@wordpress/block-editor"
export default function Edit() {
const blockProps = useBlockProps()
return (
<div {...blockProps}>
<div className="our-placeholder-block">University Footer Placeholder</div>
</div>
)
}
src/footer/index.js(精简成导入拼装):
import { registerBlockType } from "@wordpress/blocks"
import metadata from "./block.json"
import Edit from "./edit"
registerBlockType(metadata.name, {
edit: Edit
})
header/eventsandblogs 两个文件夹结构完全相同,只是 block.json 的 name/title、edit.js 的占位文字、render.php 的内容各自对应替换——不重复贴代码。
关键改动点:
- 两个终端窗口同时运行:
npm start(旧的构建任务,服务还没迁移完的 Block)+npm run blocks(新的自动扫描任务,服务已经迁移到src/的 Block)——作者提到自己试过至少十种「合并成一条命令」的方案都不完美,干脆维持两个终端窗口分别跑,等全部迁移完再彻底切换 - 把
Edit函数拆到独立的edit.js文件:export default function Edit() {...},index.js里改成import Edit from "./edit"——这一讲的 Footer 编辑器内容还很简单(一行 JSX),但这个拆分习惯是为了后面几讲要迁移的复杂 Block(Banner、Slideshow 这种有上百行 JSX 的)打基础,避免index.js一个文件塞进所有逻辑 useBlockProps()——apiVersion: 3下必须手动接管的选中态外壳:用了新版apiVersion之后,WordPress 不再自动给 Block 包一层「点击后判断选中、显示蓝色边框」的外壳逻辑,需要开发者自己调用useBlockProps()拿到一组必要的属性(选中态 class、点击事件等),用展开语法{...blockProps}铺到最外层的包装元素上——这跟 Block Theme 章节 EP154 处理 Quiz Block 时遇到的坑完全是同一个原理- 不加
useBlockProps()的具体症状:点击这个 Block 的占位内容,右侧检查器面板不会正确识别/高亮当前选中的是哪个 Block(没有蓝色选中边框),哪怕内容本身能正常显示——这是一个「看起来能用,但编辑器交互层面是坏的」的隐蔽问题,容易被忽略 - 迁移 Header/Events and Blogs 的完整流程回顾(跟迁移 Footer 完全对称):
functions.php里注释掉对应的new PlaceholderBlock(...)调用- 紧邻
register_block_type_from_metadata(__DIR__ . '/build/footer')那一行,复制一行改成对应 Block 名 - 在
src/里直接复制整个footer/文件夹、改名成新 Block 名(VS Code 里复制粘贴文件夹、按回车直接重命名,比手动新建每个文件更快) - 改
block.json的name/title - 改
edit.js里的占位文字 - 清空
render.php,从旧的our-blocks/{name}.php文件里把内容整个复制过来 - 验证前台和编辑器都正常后,删除对应的旧
our-blocks/{name}.js/{name}.php两个文件
- 作者明确表示不会逐一带着做完全部占位 Block:这门课的 Block Theme 里还有十几个类似的简单占位 Block(各种
single-*/archive-*/page-*),跟 Footer/Header/Events and Blogs 用的是一模一样的迁移套路,留作可选的课后练习,参考代码压缩包会包含已经全部迁移好的最终版本
Hook / Function 速查
| 名称 | 类型 | 用途 |
|---|---|---|
useBlockProps()(@wordpress/block-editor) | React Hook | apiVersion: 3 下手动接管 Block 选中态外壳,返回需要展开到最外层元素的属性对象 |
export default function Edit() {...} + import Edit from "./edit" | JS 模块拆分写法 | 把编辑器 JSX 拆到独立文件,index.js 只负责注册和拼装 |
常见坑
- 用了
apiVersion: 3却忘记调用useBlockProps()并展开到最外层元素——Block 内容能正常显示,但点击后不会显示选中边框,右侧检查器面板也无法正确识别当前选中的 Block - 迁移完某个 Block 后忘记删除对应的旧
our-blocks/{name}.js/{name}.php文件——虽然不影响功能(旧文件不会被引用),但会让代码库长期存在两套并行、容易混淆的实现 render.php忘记清空占位内容直接从旧文件复制粘贴,导致内容重复或格式错乱
延伸 / 后续讲座会用到
下一讲开始迁移真正复杂的 Block(比如 Banner),验证「编辑器 JSX 有上百行逻辑」的场景下,这套拆分文件的工作流同样简单好用。
Sources
Udemy:
- Become a WordPress Developer: Unlocking Power With Code — Section 29, EP218