如何将密钥传递给 ESNext 中的函数?
How do I pass a key to a function in ESNext?
我正在为 WordPress 编写一个 gutenberg 块插件,但我无法理解新的 ESNext 语法。我有一个带有 key:value 配对的字段列表。这是我正在使用的代码:
{
...
edit: function( { className, attributes, setAttributes } ) {
return (
<div className={ className }>
<label className="field">
<span className="field__label">Name</span>
<PlainText
className="field__input"
id="email"
value={ attributes.name }
onChange={ ( name ) => setAttributes( { name } ) }
/>
</label>
<label className="field">
<span className="field__label">Email</span>
<PlainText
className="field__input"
id="email"
value={ attributes.email }
onChange={ ( email ) => setAttributes( { email } ) }
/>
</label>
</div>
);
}
...
}
我希望这段代码不那么重复,避免复制粘贴。这是我得到的结果:
{
edit: function( { className, attributes, setAttributes } ) {
var fields = {
name: 'Name',
email: 'Email',
phone: 'Phone',
website: 'Website',
}
var html = [];
for ( var field_key in fields ) {
var label = fields[ field_key ];
html.push( (
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={ ( ??? ) => setAttributes( { ??? } ) }
/>
</label>
) );
}
return (
<div className={ className }>
{html}
</div>
);
},
}
如何将 field_key
变量传递给 setAttributes
函数?
我找到了解决办法。当 onChange
被触发时,for loop
已经完成并且 field_key
引用了最后一个键,"website"。为了解决这个问题,我为处理程序函数创建了一个闭包,它在当前迭代中锁定对 field_key
的引用。
const handler = (setter, key) => value => setter( { [key]: value } );
{
...
edit: function( { className, attributes, setAttributes } ) {
let fields = {
name: 'Name',
email: 'Email',
phone: 'Phone',
website: 'Website',
}
let html = [];
for ( let field_key in fields ) {
let label = fields[ field_key ];
html.push( (
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={handler( setAttributes, field_key )}
/>
</label>
) );
}
return (
<div className={ className }>
{html}
</div>
);
},
...
}
您实际上不需要 handler
函数来绑定 field_key
。如果你只是将箭头函数传递给 onChange
它将绑定 field_key
然后你可以将它传递给 setAttributes
:
for (const field_key in fields) {
const label = fields[field_key];
html.push(
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={() => { setAttributes({ [field_key]: fields[field_key] }); }}
/>
</label>
);
}
我在 Codepen 上举了一个例子来说明这一点(React 例子,但也应该适用于你的情况)。
我正在为 WordPress 编写一个 gutenberg 块插件,但我无法理解新的 ESNext 语法。我有一个带有 key:value 配对的字段列表。这是我正在使用的代码:
{
...
edit: function( { className, attributes, setAttributes } ) {
return (
<div className={ className }>
<label className="field">
<span className="field__label">Name</span>
<PlainText
className="field__input"
id="email"
value={ attributes.name }
onChange={ ( name ) => setAttributes( { name } ) }
/>
</label>
<label className="field">
<span className="field__label">Email</span>
<PlainText
className="field__input"
id="email"
value={ attributes.email }
onChange={ ( email ) => setAttributes( { email } ) }
/>
</label>
</div>
);
}
...
}
我希望这段代码不那么重复,避免复制粘贴。这是我得到的结果:
{
edit: function( { className, attributes, setAttributes } ) {
var fields = {
name: 'Name',
email: 'Email',
phone: 'Phone',
website: 'Website',
}
var html = [];
for ( var field_key in fields ) {
var label = fields[ field_key ];
html.push( (
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={ ( ??? ) => setAttributes( { ??? } ) }
/>
</label>
) );
}
return (
<div className={ className }>
{html}
</div>
);
},
}
如何将 field_key
变量传递给 setAttributes
函数?
我找到了解决办法。当 onChange
被触发时,for loop
已经完成并且 field_key
引用了最后一个键,"website"。为了解决这个问题,我为处理程序函数创建了一个闭包,它在当前迭代中锁定对 field_key
的引用。
const handler = (setter, key) => value => setter( { [key]: value } );
{
...
edit: function( { className, attributes, setAttributes } ) {
let fields = {
name: 'Name',
email: 'Email',
phone: 'Phone',
website: 'Website',
}
let html = [];
for ( let field_key in fields ) {
let label = fields[ field_key ];
html.push( (
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={handler( setAttributes, field_key )}
/>
</label>
) );
}
return (
<div className={ className }>
{html}
</div>
);
},
...
}
您实际上不需要 handler
函数来绑定 field_key
。如果你只是将箭头函数传递给 onChange
它将绑定 field_key
然后你可以将它传递给 setAttributes
:
for (const field_key in fields) {
const label = fields[field_key];
html.push(
<label className="field" key={field_key}>
<span className="field__label">{ label }</span>
<PlainText
className="field__input"
id={field_key}
value={ attributes[field_key] }
onChange={() => { setAttributes({ [field_key]: fields[field_key] }); }}
/>
</label>
);
}
我在 Codepen 上举了一个例子来说明这一点(React 例子,但也应该适用于你的情况)。