考虑以下块。
block.js
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/demo-block",
"version": "0.1.0",
"title": "Demo Block",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"attributes": {
"arr": {
"type": "array",
"default": []
}
},
"supports": {
"html": false
},
"textdomain": "demo-block",
"editorScript": "file:./index.js"
}
edit.js
import {
useBlockProps,
InspectorControls
} from '@wordpress/block-editor';
import {
Panel,
PanelBody
} from '@wordpress/components';
import './editor.scss';
import { DemoObject } from './demo';
export default function Edit({ attributes, setAttributes }) {
return (
<>
<InspectorControls>
<Panel>
<PanelBody title='Demo Setting'>
<DemoObject
arr = { attributes.arr }
update = { (newArr) => setAttributes({ arr: newArr }) }
/>
</PanelBody>
</Panel>
</InspectorControls>
<p { ...useBlockProps() }>
{ 'Demo Block – hello from the editor!' }
</p>
</>
);
}
demo.js
import { Component } from '@wordpress/element';
import { Button } from '@wordpress/components';
export class DemoObject extends Component {
constructor(props) {
super(props);
this.state = {
arr: props.arr,
updater: props.update
}
this.increase = this.increase.bind(this);
this.decrease = this.decrease.bind(this);
}
increase() {
let newArr = this.state.arr;
newArr.push("");
this.setState({ arr: newArr });
this.state.updater(newArr);
}
decrease() {
if (this.state.arr.length > 0) {
let newArr = this.state.arr;
newArr.pop();
this.setState({ arr: newArr });
this.state.updater(newArr);
}
}
render() {
return(
<div>
<Button onClick={ this.decrease }>decrease</Button>
<p>{ this.state.arr.length }</p>
<Button onClick={ this.increase }>increase</Button>
</div>
)
}
}
此块在编辑器的设置侧栏中有两个按钮。一个应该增加后端保存的数组,而另一个应该减少它。
不过,它有一个奇怪的行为。在保存(编辑站点时)或发布(在帖子中)然后重新加载页面时,您会注意到数组的长度保持不变。如果您单击站点编辑器中的增加按钮,保存按钮将保持禁用状态。并且在帖子中使用此块时,发布按钮(尽管处于活动状态)不会保存数组。
我见过类似的帖子,但没有一个解决方案。
Aduth 在有关 setAttribute
不会导致重新渲染的问题中发布了此问题的
solution。虽然症状不同,但原因是一样的
正如 Aduth 所说,所有“归结为
nextAttributeValue !== previousAttributeValue
”。他还提到,“问题是你正在改变属性,而不是创建新值,所以编辑器没有检测到发生了变化。”
concat
和slice
方法即可。这些 JavaScript 方法创建新数组而不是改变旧数组。如图所示替换 increase
和 decrease
函数。
increase() {
let newArr = this.state.arr;
newArr = newArr.concat([""]);
this.setState({ arr: newArr });
this.state.updater(newArr);
}
decrease() {
if (this.state.arr.length > 0) {
let newArr = this.state.arr;
newArr = newArr.slice(0, -1);
this.setState({ arr: newArr });
this.state.updater(newArr);
}
}