Reputation:
I'm new working with ReactJS, I started a project a simple CRUD just for practice. So, I have a table and I want to add a class so that this element disappears when I press a button
The problem is when I press the button delete, React adds a class to all elements, disappearing all of them
How to delete only the parent element of a clicked button ? I tried to get the id of an event but I don't know how to specify to what element I want to add a class.
deleteTask(e, id){
//let trDelete =
e.currentTarget.parentNode.getAttribute('key');
M.toast({html: 'Task Deleted'})
const currState = this.state.active;
this.setState({active: !currState});
}
{
this.state.tasks.map(task => {
return (
<tr data-key={task._id} key={task._id} className={this.state.active ? "scale-transition scale-out": ""}>
<td>{task.title}</td>
<td>{task.description}</td>
<td>
<button className="btn light-blue darken-4" onClick={(e) => this.deleteTask(e, task._id)}>
<i className="material-icons">
delete
</i>
</button>
<button className="btn light-blue darken-4" style={{margin: '4px'}}>
<i className="material-icons">
edit
</i>
</button>
</td>
</tr>
)
})
}
Upvotes: 2
Views: 352
Reputation: 30360
To apply CSS classes on a per-item basis, you will need to track the class(es) of each item by adding extra component state.
A simple solution here would be to update your deleteTask()
function:
deleteTask = (event, taskId) => {
this.setState(state => {
/*
Iterate each task in state, and add isDeleted to task(s) with matching id
*/
return {
tasks : state.tasks.map(task =>
(taskId === task._id ? { ...task, isDeleted : true } : { ...task }))
};
}, () => {
/*
Show toast popup after stat change
*/
M.toast({html: 'Task Deleted'});
});
}
And then update your table rendering to account for the new isDeleted
item state:
<tr data-key={task._id} key={task._id}
className={ task.isDeleted ? "scale-transition scale-out": ""}>
{ /* Existing table markup */ }
</tr>
Upvotes: 2
Reputation: 1168
The class is being added to all of them, because you're iterating over each item and assigning the class to each task item based on active
being constant.
If you want to delete or hide a task, the setState
should be affecting this.state.tasks
and not this.state.active
.
I'm guessing your update and state is intended to look more like this:
deleteTask(e, id) {
// Return new task objects to prevent mutation of state
const tasks = this.state.tasks.map(task => {
return task.id === id ? {...task, active: !task.active} : {...task};
});
// Executes callback after state update is complete
this.setState({tasks}, () => M.toast({html: 'Task Deleted'}));
}
Disclaimer: I don't know what you're using to transpile, so you might have to use the equivalent of the object spread and property shorthand.
Upvotes: 0