Reputation: 2137
I have a table being built dynamically by mapping over an array. Each item in the array gets a row. One of the columns in each of these rows is a select
. I only want that column's content to show when a button in the same row's next column is clicked.
My plan was to add some sort of a toggle bool property to each object in my array, but then when I try to toggle it in my button's onclick, my eslint is complaining because I'm trying to modify a property of the parameter I sent into the function called by the onclick.
What is the appropriate way to do this?
Here's the code for the table:
<table>
<tbody>
{myArray.map(row => (
<tr key={`test-${row.name}`}>
<td>
<div className="testClass">{row.id}</div>
</td>
<td>{row.name}</td>
<td>
<Select
options={this.getOptions(row.id)}
onSelect={this.onOptionSelect}
placeholder="Select something"
/>
</td>
<td><button onClick={() => { changeStuff(row); }}>{ row.myToggle ? 'Save' : 'Change something' }</button></td>
</tr>
))}
</tbody>
</table>
Upvotes: 1
Views: 11549
Reputation: 3932
In click handler, you can update your array altogether to show/hide the select option.
Based on my understanding, I have tried creating below snippet. This is the way i could come up with, as per my understanding. I have maintained 'hidden' field in the array of objects. Instead of 'Select' I have used a simple button. You can change accordingly. Hope this helps.
const list = [
{
name: "Person 1",
phone: "123-4567",
id: 11,
hidden:true
},
{
name: "Person 2",
phone: "123-4567",
id: 12,
hidden:true
},
{
name: "Person 3",
phone: "123-4567",
id: 23,
hidden:true
},
{
name: "Person 4",
phone: "123-4567",
id: 34,
hidden:true
},
{
name: "Person 5",
phone: "123-4567",
id: 45,
hidden:true
}
];
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
list: list
};
this.handleClick = this.handleClick.bind(this);
}
handleClick(item) {
let updatedList = this.state.list.map(obj => {
if(obj.id === item.id) {
return Object.assign({}, obj, {
hidden:!item.hidden
});
}
return obj;
});
this.setState({
list : updatedList
});
}
render() {
return (
<div>
<table>
<tbody>
{this.state.list.map(item =>
<tr key={item.itemId}>
<td>
{item.name}
</td>
<td>
{item.phone}
</td>
<td >
<button hidden={item.hidden}> Action </button>
</td>
<td>
<button
className="delete"
onClick={() => this.handleClick(item)}
>
Change
</button>
</td>
</tr>
)}
</tbody>
</table>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("app"));
table td {
font-size: 14px;
font-weight: normal;
padding: 10px;
border: 1px solid #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Upvotes: 2