I have a React Bootstrap Table
, each page of the table has 20 records. In each row, I added a button using following line
function attachFormatter(cell, row){
return (
<AttachmentManager />
);
}
<TableHeaderColumn key={uuid.v4()}
dataField={column.dataField}
dataFormat={attachFormatter}
hidden={hide}>
{column.label}
</TableHeaderColumn>
Then I have 20 buttons in this page and each row has one button. I intended to open a modal if click one of the button. But when I click one button, the openModal()
runs one time as expected, but the render()
function of my AttachmentManager
will run 20 times. How to solve this?
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>
);
}
}
And following is my modal
import React from 'react';
import SimpleModal from '../common/SimpleModal';
export default class AttachmentModal extends React.Component {
constructor (props) {
super(props);
}
render () {
return (
<SimpleModal showModal={this.props.show}
onToggleModal={this.props.onHide}
title={this.props.title}
onCancelClick={this.props.onHide}
onPrimaryButtonClick={this.props.onPrimaryButtonClick}
cancelText="Cancel"
primaryButtonText={this.props.primaryButtonText}
loading={this.props.loading}
backdrop='static'
bsStyle={this.props.bsStyle}>
{this.props.children}
</SimpleModal>
);
}
}
I was also facing the similar problem and solved it like this.
In attachFormatter, pass the row
value as props
function attachFormatter(cell, row){
return (
<AttachmentManager row={row} />
);
}
<TableHeaderColumn key={uuid.v4()}
dataField={column.dataField}
dataFormat={attachFormatter}
hidden={hide}>
{column.label}
</TableHeaderColumn>
In AttachmentManager, On click of button the set selectedRow
and showModal
value.
You can use isObjectEquivalent
function to compare the row props and selectedRow value.
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>
);
}
}
Hope this help you.