WordPress古腾堡自定义tabs区块嵌套重复器字段内容重复问题
问题核心
所有Tab共用全局tiles属性存储内容块,导致所有Tab渲染内容完全同步,调整为嵌套数据结构即可解决,修改后的完整代码如下:
import { useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import { registerBlockType } from '@wordpress/blocks'; import { Button, RichText } from '@wordpress/components'; registerBlockType("blocks/tabs", { title: __("Tabbed Blocks", "custom-blocks"), description: __("Tabbed content blocks", "custom-blocks"), icon: "smiley", category: "custom-category", keywords: [__("tabs", "custom-blocks"), __("repeat", "custom-blocks")], attributes: { tabs: { type: "array", default: [{ index: 0, tabTitle: '', tiles: [] }], }, }, edit: (props) => { const { attributes: { tabs }, setAttributes, } = props; // 默认展示第一个tab const [showTab, setShowTab] = useState(0); const handleTabClick = (index) => { setShowTab(index); }; return ( <> <div className="tabs"> <ul id="tabs-nav"> {tabs.map((t, index) => ( <li key={index}> <span onClick={() => handleTabClick(index)} id={`#tab${index}`}> <RichText placeholder="Tab title" onChange={(tabTitle) => { const newTabs = [...tabs]; newTabs[index] = { ...newTabs[index], tabTitle }; setAttributes({ tabs: newTabs }); }} value={t.tabTitle} /> </span> </li> ))} </ul> {tabs.map((t, tabIndex) => ( <div key={tabIndex} id={`tab${tabIndex}`} className={ showTab == tabIndex ? `tab-content show` : `tab-content hide` } > <div className="home-tabs"> {t.tiles.map((tile, tileIndex) => ( <div key={tileIndex} className="tab-block" > <div className="copy"> <RichText tagName="h3" placeholder="Tab Content Title" onChange={(tabTileTitle) => { const newTabs = [...tabs]; newTabs[tabIndex].tiles[tileIndex] = { ...newTabs[tabIndex].tiles[tileIndex], tabTileTitle }; setAttributes({ tabs: newTabs }); }} value={tile.tabTileTitle} /> <p> Some content... </p> </div> </div> ))} </div> </div> ))} <Button onClick={() => { const newTabs = [...tabs]; newTabs[showTab].tiles.push({ index: newTabs[showTab].tiles.length }); setAttributes({ tabs: newTabs }); }} disabled={showTab === '' || showTab >= tabs.length} > Add Tile </Button> </div> <Button onClick={() => { setAttributes({ tabs: [...tabs, { index: tabs.length, tabTitle: '', tiles: [] }], }); }} > Add Tab </Button> </> ); }, save: (props) => { return null; }, });
核心修改说明
- 移除了全局的
tiles属性,将内容块数据作为子属性嵌套到每个Tab对象中,从数据层面实现Tab间隔离 - 新增Tab时默认初始化空的内容块数组,不会继承已有Tab的内容
- 「Add Tile」按钮仅给当前激活的Tab新增内容块,不会影响其他Tab
- 修复了原代码中修改Tab标题后,Tab顺序紊乱的问题
- 补充了列表渲染的
key属性,避免React渲染异常

内容的提问来源于stack exchange,提问作者user8463989
相关产品推荐
相关产品推荐

