Reputation: 300
I have (for example) 2 components. Of course, 1 of them is Parent, and another one is a Child of Parent. My goal is to delete component by button, but when I press the delete button inside child component, function deleting next component. Maybe I forgot something?
Example: [[1],[2],[3]] - That is nested array with another arrays. I want to remove [2] (parentArray[1]). But delete function removing [3] (parentArray[2]) and i have [[1],[2]]. That is my trouble.
Parent component:
import React from 'react'
import classes from './Kanban.module.scss'
import Card from './Card/Card.js'
export default class Kanban extends React.Component {
constructor(props) {
super(props);
this.state = {
cards: [
]
}
this.createCardHandler = this.createCardHandler.bind(this);
this.deleteCardHandler = this.deleteCardHandler.bind(this);
}
createCardHandler() {
this.setState({
cards: this.state.cards.concat({ id: this.state.cards.length })
})
}
deleteCardHandler(index) {
this.setState(prevState => {
let cards = [...prevState.cards]
cards.splice(index, 1)
return {
cards: cards
}
})
}
render() {
let cards = null;
cards = this.state.cards.map((cards, id) => {
return (
<Card
index={cards.id}
id={cards.id}
onDelete={this.deleteCardHandler.bind(this, id)}
/>
)
})
return (
<>
<div>
<button className={classes.CreateCardButton} onClick={this.createCardHandler}>+</button>
{cards}
</div>
</>
)
}
}
Child component:
import React from 'react'
import classes from './Card.module.scss'
import List from './List/List.js'
export default class Card extends React.Component {
constructor(props) {
super(props);
this.state = {
lists: []
}
this.CreateListButton = this.CreateListButton.bind(this);
}
CreateListButton() {
this.setState({
lists: this.state.lists.concat('List')
})
}
deleteListHandler(index) {
let lists = [...this.state.lists]
lists.splice(index, 1)
this.setState({
lists
})
}
render() {
let lists = null
lists = this.state.lists.map((lists, index) => {
return (
<List
index={this.state.lists.length - 1}
onDelete={this.deleteListHandler.bind(this, index)}
/>
)
})
return (
<div className={classes.Card}>
<button className={classes.DeleteCardButton} onClick={this.props.onDelete}>✖</button>
<input maxLength='18' autoFocus className={classes.InputTitleInCard}></input>
{lists}
<button className={classes.CreateNewListButton} onClick={this.CreateListButton}>CREATE NEW LIST</button>
</div>
)
}
}
Upvotes: 0
Views: 491
Reputation: 11
When you set the state use the Spread Operator it worked for me.
this.setState({
lists
})
changed like this
this.setState({
[...lists]
})
Upvotes: 1
Reputation: 399
The issue is with you delete handler. Initially the state of your Kanban class is []. Then, lets say you add 4 cards, it would then become
[{id: 0}, {id: 1}, {id: 2}, {id: 3}]
So, if you delete say the 2nd card, your new state becomes,
[{id: 0}, {id: 2}, {id: 3}]
Now, if you try to delete the 3rd card, i.e. id=2, your handler deletes the index 2 element from state, i.e. element with id 3. So, the element your click, the next element would get deleted. Don't rely on the array index(this mapping won't work once you delete any card), rely on the id's that you have created for cards. The way you have written delete handler is not proper. Here is a solution, this should fix the issue.
deleteCardHandler(index) {
this.setState(previousState => previousState.filter(card => card.id !== index))
}
This basically returns an array with all the elements except for the one on which you clicked delete. Hope it helps!!!
Upvotes: 0
Reputation: 1156
Please add an index prop to your child component
cards = this.state.cards.map((card, index) => {
return (
<Card
index={card.id}
id={card.id}
//Here i giving child component function from parent component
onDelete={this.deleteCardHandler.bind(this, index)}
/>
)
})
Upvotes: 0