Reputation: 13
I created a simple class method called handleChange
with a parameter of id
under the class App
.
I tried to call this handleChange
method from a child function component called TodoItem
.
When I clicked on the checkbox, the browser returned a TypeError
saying that props.handleChange(props.item.id) is not a function
, as shown in the pictures:
Can someone explain what is wrong on my codes in TodoItem
?
App
class component:
import React, { Component } from "react";
import TodoItem from "./TodoItem";
import todosData from "./todosData";
class App extends Component {
constructor() {
super();
this.state = {
todos: todosData,
};
this.handleChange = this.handleChange(this);
}
handleChange(id) {
console.log("changed", id);
}
render() {
const todoItems = this.state.todos.map((item) => (
<TodoItem key={item.id} item={item} handleChange={this.handleChange} />
));
return <div className="todo-list">{todoItems}</div>;
}
}
export default App;
TodoItem
functional component:
import React from "react";
function TodoItem(props) {
return (
<div className="todo-item">
<input
type="checkbox"
checked={props.item.completed}
onChange={(e) => props.handleChange(props.item.id)}
/>
<p>{props.item.text}</p>
</div>
);
}
export default TodoItem;
Upvotes: 1
Views: 7072
Reputation: 1383
In your constructor you're not properly binding your function
class App extends Component {
constructor(props) {
super(props);
this.state = {
todos: todosData,
};
this.handleChange = this.handleChange.bind(this)//<-- This is right
//this.handleChange = this.handleChange(this);//<-- This is wrong
}
Upvotes: 0
Reputation: 4364
You either need to bind handleChange
on using or convert it into arrow functions. I prefer arrow functions.
binding;
this.handleChange = this.handleChange.bind(this);
arrow function;
handleChange = (id) => {
console.log("changed", id);
}
P.S: if you don't change the item in the child component there is no point to pass item into child and pass item.id to props.handleChange since it is accessible in the parent component in the first place.
P.S.2: you actually invoke handleChange
instead of binding it in your constructor.
Upvotes: 2