React Bootstrap Table在每一行都有按钮来创建模态,但是一个按钮会多次调用模态的渲染

时间:2017-10-27 20:05:25

标签: reactjs react-bootstrap-table react-modal

我有React Bootstrap Table,表格的每一页都有20条记录。在每一行中,我使用以下行添加了一个按钮

function attachFormatter(cell, row){
     return (
        <AttachmentManager />
     );
 }
 <TableHeaderColumn key={uuid.v4()}
                   dataField={column.dataField}
                   dataFormat={attachFormatter}
                   hidden={hide}>
                    {column.label}
</TableHeaderColumn>

然后我在这个页面中有20个按钮,每行有一个按钮。如果单击其中一个按钮,我打算打开一个模态。但是,当我点击一个按钮时,openModal()按预期运行一次,但render()的{​​{1}}功能将运行20次。怎么解决这个问题?

AttachmentManager

以下是我的模态

export default class AttachmentManager extends React.Component {
    constructor (props) {
        super(props);
        this.state = {showModal: false};
    }

    openModal() {
        alert('test');
    }

    render () {
        return (
      <button onClick={this.openModal.bind(this)} className="btn btn-default">Add Projects
        <AttachmentModal show={this.state.showModal}/>
      </button>
        );
    }
}

2 个答案:

答案 0 :(得分:1)

我也遇到了类似的问题并且像这样解决了。

在attachFormatter中,将row值作为props

传递
function attachFormatter(cell, row){
     return (
        <AttachmentManager row={row} />
     );
 }
 <TableHeaderColumn key={uuid.v4()}
                   dataField={column.dataField}
                   dataFormat={attachFormatter}
                   hidden={hide}>
                    {column.label}
</TableHeaderColumn>

在AttachmentManager中,单击按钮,设置selectedRowshowModal值。 您可以使用isObjectEquivalent函数来比较行道具和selectedRow值。

export default class AttachmentManager extends React.Component {
  constructor(props) {
   super(props);
   this.state = {
    showModal: false,
    selectedRow: null
   };
  }

  openModal() {
   this.setState((prevState, props) => {
    return {
     selectedRow: props.row,
     showModal: true
    }
   });
  }

  isObjectEquivalent(a, b) {
   // Create arrays of property names
   var aProps = Object.getOwnPropertyNames(a);
   var bProps = Object.getOwnPropertyNames(b);

   // If number of properties is different,
   // objects are not equivalent
   if (aProps.length != bProps.length) {
    return false;
   }

   for (var i = 0; i < aProps.length; i++) {
    var propName = aProps[i];

    // If values of same property are not equal,
    // objects are not equivalent
    if (a[propName] !== b[propName]) {
     return false;
    }
   }

   // If we made it this far, objects
   // are considered equivalent
   return true;
  }

  render() {
    return ( 
    <div>
        <button onClick = {this.openModal.bind(this)} className = "btn btn-default"> Add Projects </button> 
        {this.state.showModal && this.isObjectEquivalent(this.props.row, this.state.selectedRow) ? ( < AttachmentModal show = {this.state.showModal} />) : null} 
     </div>
      );
     }
    }

希望这对你有所帮助。

答案 1 :(得分:0)

将组件更改为PureComponent。

export default class AttachmentManager extends React.PureComponent {
...
}

为所有按钮添加一个键。

 <button key={uuid.v4()} onClick={this.openModal.bind(this)} className="btn btn-default">Add Projects
        <AttachmentModal show={this.state.showModal}/>
      </button>