Search code examples
javascriptreactjsreact-reduxreact-props

Function passed as props not a function


I am trying to pass a function named addtodo as a props from a class. I have passed the function as below

export class Todo extends Component {
    constructor(props) {
        super(props);
        this.state = {todos:[]};

        this.addtodo = this.addtodo.bind(this);
        this.deleteTodo = this.deleteTodo.bind(this);

      }
    componentDidMount(){
axios.get('https://jsonplaceholder.typicode.com/posts').then(res=>{
    this.setState({
       todos:res.data

    })
})
    }
  addtodo(todo){
        todo.id=Math.floor(Math.random()*100)
        todo.completed=true
       const todos=[...this.state.todos,todo]
       this.setState({
         todos:todos
       })
         }
    deleteTodo(id){
        const todo=this.state.todos.filter(todo=>{
         return(
            todo.id!==id
         )
        }
            )
            this.setState({
                todos:todo
            })
    }
    render() {
        return (
            <div>
           <h1 className="center-align"> Todos</h1>
                   <Todolist todos={this.state.todos} deleteTodo={this.deleteTodo}/>
                   <Addtodo addtodo={this.addtodo}/>
            </div>
        )
    }
}

export default Todo

And in Addtodo.js, I am using the function as props as below

 class Addtodo extends Component {
      constructor(props) {
    super(props);
    this.state = { title:'',
    body:''
};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);

  }

handleChange(e){
    this.setState({
        [e.target.id]:[e.target.value]
    })
    }

    handleSubmit(e){
        e.preventDefault()
        this.props.addtodo(this.state)
        this.setState({
            title:'',
            body:''
        })
        }


    render() {
        return (
            <form className="col s12" onSubmit={this.handleSubmit}>
            <div className="row">
              <div className="input-field col s6">
                <input placeholder="Add title" id="title" type="text" className="validate" onChange={this.handleChange}/>
              </div>
              <div className="input-field col s6">
                <input placeholder="Add body" id="body" type="text" className="validate" onChange={this.handleChange}/>
              </div>
              <button type="submit">Submit</button>
              </div>
              </form>
        )
    }
}

export default Addtodo

But I am getting the error Uncaught TypeError: this.props.addtodo is not a function. I checked for spelling error as well but could not get why this is not working. Whereas if I pass it as a props to another class and simply log a hello message it is working.


Solution

  • I successfully run your code on the stackblitz, and there are no errors

    and i found another bug,

    before

    handleChange(e) {
        this.setState({
          [e.target.id]: [e.target.value]
        });
      }
    

    after

    handleChange(e) {
        this.setState({
          [e.target.id]: e.target.value
        });
      }
    

    check stackblitz demo

    tip: Because i don't have enough points, so i cannot add comments, can only editor answer

    update:

    before:

    function App() {
      return (
        <BrowserRouter>
          <div className="container">
            <Addtodo />
            <Switch>
              <Route exact path="/" component={Todo} />
              <Route path="/:id" component={Task} />
            </Switch>
          </div>
        </BrowserRouter>
      );
    }
    
    export default App;
    
    
    function App() {
      return (
        <BrowserRouter>
          <div className="container">
            <Switch>
              <Route exact path="/" component={Todo} />
            </Switch>
          </div>
        </BrowserRouter>
      );
    }
    
    render(<App/>, document.getElementById('root'))
    

    Please check the code is not more than one Addtodo ?