从父组件向子组件添加动态html属性 - React.js

6
子组件:
export default class Button extends React.Component {
constructor(props) {
    super(props);
}
render() {
 return(
        <div className="form-group">
            <button

                // Need to add dynamic html attr here e.x: data-id

                key={index} 
                id={id} 
                className={`btn btn-default ${componentClass ? componentClass : null }`} 
                type="button"
                onClick={this.props.onClick}> 

                {text}

            </button>
        </div>
    );}}

父组件:

import Button from './Button';

Class App extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <div className="s">
             <Button data-id="exampleData" />  // Need to add data-id attr to child button
            </div>
        );
    }

按钮组件,具有自己的默认属性,如上所述:id、className、type、onClick。

父组件会调用按钮组件并添加一些额外的属性,如data-id、onChange。

注:经过搜索了解到,我可以使用以下方式来使用扩展运算符:

父组件:

let dynamicAttributes = {"data-id":"someString", "data-attr":"someString", "data-url":"someString"};
    return (
        <div className="s">
         <Button dataSrc={ btnSrc } {...dynamicAttributes} />
        </div>
    );

我不知道如何将Button组件中的dynamicAttributes称为html属性。

期待一个好的解决方案。提前感谢。

使用解构和Babel时出现错误(意外标记),如下图所示。

enter image description here

注意:已经安装了preset-env和preset-react。
2个回答

4
您可以在子组件中使用rest解构模式。根据文档rest属性收集剩余的可枚举自有属性键,这些键尚未被解构模式拾取。当您直接将props分配给DOM元素时,应谨慎使用rest解构,因为从v16开始,不会对属性进行检查,所有属性都允许传递到DOM元素,因此即使与其无关,这些属性也将传递到您不希望的DOM元素。请注意将要解构的所有不想传递给DOM的属性单独解构。示例片段:
export default class Button extends React.Component {
  constructor(props) {
      super(props);
  }
  render() {
     const { onClick, dataSrc, ...rest } = this.props;
     return(
          <div className="form-group">
              <button
                  {...rest}
                  key={index} 
                  id={id} 
                  className={`btn btn-default ${componentClass ? componentClass : null }`} 
                  type="button"
                  onClick={onClick}> 

                  {text}

              </button>
          </div>
      );
  }
}

@Balaji731,请检查这个问题,https://github.com/babel/babel-preset-env/issues/49。在这里提到,所有的stage-x问题都不包含在preset-env中,而rest-spread是一个stage-3的提案,因此你需要一个插件。 - Shubham Khatri
感谢@Shubham Khatri,还需要澄清一点,如果我需要使用所有的es6功能,我需要安装以下预设和插件:babel-preset-stage-3、babel-preset-env和babel-polyfill。除此之外,我还需要安装其他东西吗? - Balaji731
以上三个对我来说都有效,不确定是否在其他功能中需要其他内容。 - Shubham Khatri
1
假设我们在子组件中有更多的按钮。那么,我可能需要使用不同的条件。有些样式适用于一个按钮,有些则适用于其他按钮。那么,在这种情况下,如何从父组件向子组件传递值呢? - Coder
1
@AkhilaHegde 你可以创建多个带有不同样式的对象,并将它们传递给相应的按钮。或者你可以创建一个带有共同属性的对象,然后在传播共同属性的同时,传递额外的属性。 - Shubham Khatri
显示剩余4条评论

3
如果你想传递选择性的 props,可以这样做:
<button 
  dataSrc={ btnSrc }
  data-id={this.props.data-id}
  data-attr={this.props.data-attr}
  data-url={this.props.data-url}
  key={index} 
  id={id} 
  className={`btn btn-default ${componentClass ? componentClass : null }`} 
  type="button"
  onClick={this.props.onClick}
> 
  {text}
</button>

如果你想传递所有的动态属性,你应该相应地解构props。像这样:{onClick, dataSrc, ...dynamicAttrs} = this.props; 然后像这样传递它们:

<button 
  {...dynamicAttrs}
  dataSrc={ btnSrc }
  key={index} 
  id={id} 
  className={`btn btn-default ${componentClass ? componentClass : null }`} 
  type="button"
  onClick={this.props.onClick}
> 
  {text}
</button>

另外,参考此网址:传递属性


我们已经有了babel preset-env,但在{...rest}中抛出错误(意外的标记)。安装babeljs.io/docs/plugins/transform-object-rest-spread后,它可以正常工作。既然我们有了preset-env,那么为什么还需要额外的插件来支持这个功能呢? - Balaji731

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