I am trying to build a todo list app with React. Getting the error “Cannot read property of handleChange undefined”. Below is the code i am working on. Moreover, todosData is an array of objects having id, text and completed(boolean – true/false) as properties.
JavaScript
x
39
39
1
import React from "react";
2
import './App.css';
3
import List from './Components/Todo-Startup/content';
4
import todosData from './Components/Todo-Startup/todosData';
5
6
class App extends React.Component {
7
8
constructor(){
9
super()
10
this.state = {
11
todos: todosData
12
}
13
this.handleChange = this.handleChange.bind(this)
14
}
15
16
handleChange(id){
17
console.log("Changed", id)
18
19
}
20
21
render() {
22
const todoComponents = this.state.todos.map(function(task){
23
return (
24
<List key={task.id}
25
task={task}
26
handleChange={this.handleChange} />
27
)
28
})
29
30
return (
31
<div className = "App">
32
{todoComponents}
33
</div>
34
)
35
}
36
}
37
38
export default App;
39
The content.js is as follows,
JavaScript
1
18
18
1
import React from 'react';
2
3
const List = function (props){
4
return (
5
<div className="todo-list">
6
<input
7
onChange={function(){props.handleChange(props.task.id)
8
}}
9
type="checkbox"
10
checked={props.task.completed}/>
11
<p>{props.task.text}</p>
12
</div>
13
14
);
15
}
16
17
export default List;
18
And finally the array todosData,
JavaScript
1
26
26
1
const todosData = [
2
{
3
id: 1,
4
text: "Take out the trash",
5
completed: true
6
},
7
{
8
id: 2,
9
text: "Grocery Shopping",
10
completed: false
11
},
12
{
13
id: 3,
14
text: "Get a hair cut",
15
completed: true
16
},
17
{
18
id: 4,
19
text: "Study & Practice JavaScript",
20
completed: true
21
}
22
23
]
24
25
export default todosData;
26
Advertisement
Answer
Because this
is function-scoped, except for arrow-functions.
JavaScript
1
6
1
const todoComponents = this.state.todos.map(task => (
2
<List key={task.id}
3
task={task}
4
handleChange={this.handleChange} />
5
))
6
Alternative, if you have to use function
.
JavaScript
1
7
1
const that = this;
2
const todoComponents = this.state.todos.map(function (task) (
3
<List key={task.id}
4
task={task}
5
handleChange={that.handleChange} />
6
));
7
See also How to access the correct `this` inside a callback?