WordPress Gutenberg问题:复制区块时属性被覆盖
自定义WordPress Gutenberg区块复制后数组属性被覆盖的问题
我开发了一个自定义WordPress Gutenberg区块,其中包含可按需添加/删除的按钮列表。该功能整体运行正常,但存在一个问题:在编辑模式下复制区块后,副本会覆盖原区块的数组属性值;保存并刷新页面后,数组值才会变为相互独立的状态。请问是否有人了解该现象?
简化代码示例
// Attributes definition: ... attributes: { buttons: { type: 'array', default: [] } } ... const buttons = props.attributes.buttons ... // Edit inspector controls: buttons.length > 0 && buttons.map( function( button, index ) { return el( TextControl, { label: 'Text', value: button.text, onChange: function( newText ) { let newButtons = [ ...buttons ] newButtons[ index ][ 'text' ] = newText props.setAttributes( { buttons: newButtons } ) } } ) } // Edit / Save output: buttons.length > 0 && buttons.map( function( button, index ) { return el( 'a', { key: 'button-' + index }, button.text ) } )
问题原因
这是Gutenberg编辑模式下的浅拷贝机制导致的:复制区块时,数组类型的属性只会做浅拷贝——新数组和原数组里的按钮对象指向同一个内存地址。你代码里修改按钮文本时,只拷贝了数组外壳,内部的按钮对象还是原引用,所以修改副本的按钮内容时,原区块的对应对象也会被同步修改。只有保存刷新后,区块数据从数据库重新加载,才会生成完全独立的对象实例。
解决方法
1. 对数组内的按钮对象做深拷贝
修改onChange里的逻辑,确保每个按钮对象都是独立的副本:
onChange: function( newText ) { // 遍历数组,对每个按钮对象做浅拷贝(按钮是简单对象,浅拷贝足够) let newButtons = buttons.map(btn => ({ ...btn })); newButtons[ index ].text = newText; props.setAttributes( { buttons: newButtons } ); }
如果按钮对象有嵌套结构,就需要用递归深拷贝,不过这里按钮只有text属性,浅拷贝每个对象就够了。
2. 避免用数组索引作为key
你现在用button-${index}作为key,当数组元素增删时,索引会变化,可能导致React渲染错误。建议给每个按钮添加唯一ID,用ID作为key:
// 示例:添加按钮时生成唯一ID const addNewButton = () => { const uniqueId = `btn-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`; const newBtn = { id: uniqueId, text: '新按钮' }; props.setAttributes({ buttons: [...buttons, newBtn] }); }; // 渲染按钮时使用ID作为key buttons.length > 0 && buttons.map( button => { return el( 'a', { key: button.id }, button.text ) } )
内容的提问来源于stack exchange,提问作者Kristo
相关产品推荐
相关产品推荐

