如何在ESNext中将键传递给函数?

3

我正在为WordPress编写一个古腾堡区块插件,但我很难理解新的ESNext语法。我有一个带有键值对的字段列表。这里是我已经可以工作的代码:

{
  ...
  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={(name) => setAttributes({[name]: attributes[name]})} - dfsq
@dfsq,它没起作用。我也尝试了你的代码,但是使用 field_key 而不是 name,那也不起作用。 - forsvunnet
1
错误。应该是 onChange={(name) => setAttributes({[name]: fields[name]})} - dfsq
几乎成功了,但还差一点。我用这个代码 onChange={( v ) => setAttributes({ [field_key]: v })} 让它工作了,但现在我遇到的问题是它只更新最后一个字段。 - forsvunnet
2个回答

2

您实际上不需要使用 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的例子,但在您的情况下也应该适用)。


0
我找到了一个解决方案。在触发onChange时,for循环已经完成,并且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>
    );
  },
  ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接