Aditya Chauhan
Aditya Chauhan

Reputation: 23

ReactJS: Uncaught TypeError: this.props.delete is not a function

A todo app using react. items are stored in an array. This is my child component which renders array elements from ItemList(parent).

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

class App extends React.Component {

  constructor(){
    super();
    this.onClickfn = this.onClickfn.bind(this);
  }
  componentWillReceiveProps(newProps) {    
      console.log('Component WILL RECIEVE PROPS!')
    }

  onClickfn(){
    // debugger;
    // self = this;
    this.props.delete();
  }

  render() {
    // debugger;
          var todoEntries = this.props.entries;
          var x=todoEntries.map((i) => {
            // debugger;
              return (
                <div>
                  <span key={i.key}>{i.id} {i.text} <button onClick={this.onClickfn}>x</button></span>
                </div>
                );
          });
          return(
          <div>
            <div>{x}</div>
          </div>
          );
     }
}

export default App;

This is the parent component.
import React from 'react'; import App from './App.js';

class ItemList extends React.Component{

    constructor(){
        super();
        this.state = {
            ItemsArray : [ { /*active : '',*/ id : 1} ]
        };
    }

    componentWillUpdate(nextProps, nextState) {
      console.log('Component WILL UPDATE!');
    }

    componentDidUpdate(prevProps, prevState) {
      console.log('Component DID UPDATE!')
    }

    clickHandler(e){
        // debugger;
        var n=0;
        var items = this.state.ItemsArray;
        var id = items[n].id++;
        items.push(
            {
                // active : 'X',
                id : id,
                text : this._inputElement.value,
                key : Date.now()
            }
        );

        this.setState( {ItemsArray:items} );

        this._inputElement.value='';
        e.preventDefault();
    }

    delete(id){
        debugger;
        this.state.ItemsArray.splice(id,1);
        this.setState(ItemsArray:ItemsArray);
    }

    render(){
        return (
            <div>
                <form onSubmit={this.clickHandler.bind(this)}>
                    <input type='text' placeholder='enter task' ref={(a) => this._inputElement = a}/>
                    <button type='submit'>Add</button>
                </form>
                <div>
                    <App entries={this.state.ItemsArray}/>
                </div>
            </div>
            );
    }
}
export default ItemList;

Upvotes: 1

Views: 7868

Answers (2)

MrCode
MrCode

Reputation: 64536

Pass a delete function to the App:

<App entries={this.state.ItemsArray} deleteFunc={this.delete.bind(this)} />

In the App where you output the list, call the function with the id argument

<span key={i.key}>{i.id} {i.text} <button onClick={() => { this.props.deleteFunc(i.id) }}

Finally, in your delete function, don't use splice. Instead, filter the array and set the state:

delete(id){
  this.setState({
    ItemsArray: this.state.ItemsArray.filter((x) => x.id != id )
  });
}

Upvotes: 1

duwalanise
duwalanise

Reputation: 1302

You need to pass delete function as a props in App component

<div>
  <App entries={this.state.ItemsArray} delete={this.delete.bind(this)}/>
</div>

Upvotes: 2

Related Questions