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.
import React from "react"; import './App.css'; import List from './Components/Todo-Startup/content'; import todosData from './Components/Todo-Startup/todosData'; class App extends React.Component { constructor(){ super() this.state = { todos: todosData } this.handleChange = this.handleChange.bind(this) } handleChange(id){ console.log("Changed", id) } render() { const todoComponents = this.state.todos.map(function(task){ return ( <List key={task.id} task={task} handleChange={this.handleChange} /> ) }) return ( <div className = "App"> {todoComponents} </div> ) } } export default App;
The content.js is as follows,
import React from 'react'; const List = function (props){ return ( <div className="todo-list"> <input onChange={function(){props.handleChange(props.task.id) }} type="checkbox" checked={props.task.completed}/> <p>{props.task.text}</p> </div> ); } export default List;
And finally the array todosData,
const todosData = [ { id: 1, text: "Take out the trash", completed: true }, { id: 2, text: "Grocery Shopping", completed: false }, { id: 3, text: "Get a hair cut", completed: true }, { id: 4, text: "Study & Practice JavaScript", completed: true } ] export default todosData;
Advertisement
Answer
Because this
is function-scoped, except for arrow-functions.
const todoComponents = this.state.todos.map(task => ( <List key={task.id} task={task} handleChange={this.handleChange} /> ))
Alternative, if you have to use function
.
const that = this; const todoComponents = this.state.todos.map(function (task) ( <List key={task.id} task={task} handleChange={that.handleChange} /> ));
See also How to access the correct `this` inside a callback?