Skip to content

Issue with component array filter

I want to create multiple components and delete them by pressing on button click. I created the components. But i can’t delete it.

state = {
    data: '',
    todoCard: [],
    id: 0

}

addCard() {
    var action = this.state.todoCard.concat(<TodoCard deleteCard={() => this.deleteCard(this.state.id)}
                                                      key={this.state.todoCard.length}/>);
    this.setState({id: Math.random() + 1, todoCard: [...action]})
}

deleteCard(id) {
    const cards = [...this.state.todoCard];
    const updatedList = cards.filter(item => this.state.id !== id);
    this.setState({todoCard: updatedList});
}

I wanted to give unique id to the Card component. But when i click one of cards’ buttons,all of cards are gone. I displayed the component array like this:

{this.state.todoCard

Answer

From my understanding of your question, and the portion of code you have displayed. You’re trying to remove a “card” from your list of cards in state todoCard.

Your todoCards array contains components, you cannot interact with these attached components, the way you are attempted to since they do not have the attributes like the id you are trying to use to filter.

My suggestion is to store the data necessary to create your TodoCard components as an object or Number value in your todoCard array, rather than an array of components. Then you can more easily filter based on that data. When you go to render, you can map the data into components as show below:

import React from "react";


class TodoCard extends React.Component {
    render() {
        return (<div onClick={this.props.deleteCard}>{this.props.value}</div>);
    }
}

class App extends React.Component {

    state = {
        data: '',
        todoCard: [],
        id: 0
    };

    addCard() {
        this.setState({
            id: Math.random() + 1,
            todoCard: [...this.state.todoCard, this.state.id]
        })
    }

    deleteCard(id) {
        this.setState({
            todoCard: this.state.todoCard.filter(item => item !== id)
        });
    }

    render() {
        return (
            <div className="App">
                <button onClick={() => this.addCard()}>Add</button>
                {this.state.todoCard.map((e, i) => (
                    <TodoCard deleteCard={() => this.deleteCard(e)}
                              key={i}
                              value={e}/>
                ))}
            </div>
        );

    }
}

export default App;

Here is an implementation where each element in todoCard is an object instead of Number.

import './App.css';
import React from "react";


class TodoCard extends React.Component {
    render() {
        return (<div onClick={this.props.deleteCard}>{this.props.value}</div>);
    }
}

class App extends React.Component {

    state = {
        data: '',
        todoCard: [],
        id: 0
    };

    addCard() {
        this.setState({
            id: Math.random() + 1,
            todoCard: [...this.state.todoCard, {id: this.state.id}]
        })
    }

    deleteCard(id) {
        this.setState({
            todoCard: this.state.todoCard.filter(item => item.id !== id)
        });
    }

    render() {
        return (
            <div className="App">
                <button onClick={() => this.addCard()}>Add</button>
                {this.state.todoCard.map(({id}, i) => (
                    <TodoCard deleteCard={() => this.deleteCard(id)}
                              key={i}
                              value={id}/>
                ))}
            </div>
        );
    }
}

export default App;