Gutenberg:如何限制InnerBlocks内区块数量并自动移除多余区块
WordPress列区块克隆:切换列数时自动移除多余子区块的解决方案
你当前的代码无法实现需求的核心原因是:直接调用innerBlocks.slice()只是生成了一个新数组,并没有修改WordPress区块编辑器中实际存储的子区块状态。区块编辑器的状态是不可变的,必须通过官方提供的core/block-editor dispatch API来更新子区块。
解决方案代码示例
import { useSelect, useDispatch } from '@wordpress/data'; import { InnerBlocks } from '@wordpress/block-editor'; import { useEffect } from '@wordpress/element'; const CustomColumnBlockEdit = ({ attributes, clientId }) => { // 假设allowedBlocksCount是你定义的列数属性(1/2/3) const { allowedBlocksCount } = attributes; // 通过useSelect获取当前区块的子列表 const { innerBlocks } = useSelect( (select) => ({ innerBlocks: select('core/block-editor').getBlocks(clientId), }), [clientId] ); // 获取编辑器的dispatch方法,用于修改子区块 const { replaceInnerBlocks } = useDispatch('core/block-editor'); // 监听列数或子区块数量变化,自动移除多余区块 useEffect(() => { if (innerBlocks.length > allowedBlocksCount) { // 保留前allowedBlocksCount个区块,丢弃后面的 const filteredBlocks = innerBlocks.slice(0, allowedBlocksCount); // 调用官方API更新子区块,第三个参数false表示不触发区块选中状态变化 replaceInnerBlocks(clientId, filteredBlocks, false); } }, [innerBlocks.length, allowedBlocksCount, clientId, replaceInnerBlocks]); // 控制添加按钮的显示:只有子区块数量未达上限时才显示 return ( <InnerBlocks renderAppender={() => innerBlocks.length < allowedBlocksCount ? <InnerBlocks.ButtonBlockAppender /> : null } /> ); }; export default CustomColumnBlockEdit;
关键说明
- 状态获取与修改分离:通过
useSelect获取最新的子区块状态,通过useDispatch提供的replaceInnerBlocks方法修改状态,这是WordPress区块开发的标准模式。 - 副作用触发逻辑:用
useEffect监听allowedBlocksCount(用户选择的列数)和innerBlocks.length(当前子区块数量)的变化,仅在两者不匹配时执行移除操作。 - 添加按钮控制:通过
renderAppender控制添加按钮的显示,避免用户在达到列数上限后继续添加子区块。
内容的提问来源于stack exchange,提问作者Mohamed Mohamed
相关产品推荐
相关产品推荐

