我正在创建一个具有许多属性的古腾堡块,并尝试为可以通过输入字段更改的属性创建一个通用函数。对于属性
title
我有:
<RichText
onChange={this.props.onTitleChange}
value={this.props.title}
/>
和
function onTitleChange(value) {
setAttributes({title: value});
}
这有效。现在,虽然我希望创建一个通用函数,其中
setAttributes()
title
可以是我从 React onChange
传递的任何内容。我尝试了另一个功能onValueChange
:
<RichText
onChange={this.props.onValueChange.bind("title")}
value={this.props.title}
/>
和
function onValueChange(value) {
setAttributes({this: value});
}
这不起作用,因为“this”不是我的块的属性。即使我的函数
this
中的 onValueChange
等于“标题”,它是通过 bind()
函数传递的。
我不确定我想做的事情是否可行,因为我不完全理解 setAttributes()
函数,但如果可以完成,它将节省大量时间和额外的代码,因为否则我将不得不为我的所有属性创建一个 onXChange()
函数。所以我的问题是:如何使用 setAttributes()
设置动态属性的值?
事实证明我所要做的就是将
this
括在括号中,所以:
function onValueChange(value) {
setAttributes({[this]: value});
}
保留绑定属性:
onChange={onValueChange.bind('title')}
另一种选择是使用
setAttributes
内联,如下所示:
onChange={ title => setAttributes( { title } ) }
确保将
title
更改为属性名称。
目前我能想到这个:
class MyComponent extends React.Component {
constructor(props) {
super(props);
// create a ref to store the textInput DOM element
this.textInput = React.createRef();
}
render() {
// tell React that we want to associate the ref
// with the `textInput` that we created in the constructor
<RichText
onChange={ ()=> this.props.onValueChange("title",value) }
value={this.props.title}
ref={this.textInput}
/>
}
}
function onValueChange(property ,value) {
let element = ReactDOM.findDOMNode(this.refs.textInput);
element.setAttributes({property: value});
}
PS: Not Sure wheather this is going to work but yeah you can give a try.
在这里的答案中找到[这个]真是太棒了。我试图更进一步,这对我来说更简单!
现在我有了一个组件,可以反复使用它来实现我想要的所有属性。
export const CustomComponents = {
CustomRangeControl: (val, attribute, setAttributes) => {
return (
<RangeControl
label={[attribute]}
value={val}
onChange={(value) => setAttributes({[attribute]: value}) }
min={20}
max={800}
/>
);
}
}
现在我可以像这样将它添加到我的块中
<InspectorControls>
<PanelBody ...>
{CustomComponents.CustomRangeControl(width, "width", setAttributes)}
{CustomComponents.CustomRangeControl(height, "height", setAttributes)}
...
</PanelBody>
</InspectorControls>