I have a simple To do app that takes user input through a prompt and adds it to a list. I want to change the prompt and replace it with a text input bar. I've been having trouble implenting onChange and I'm hitting a wall trying to figure this out. I really appreciate the help as a beginner trying to learn.
import React, { useState } from 'react';
let id = 0
const Todo = props => (
<li>
<input type="checkbox" checked={props.todo.checked} onChange={props.onToggle} />
<button onClick = {props.onDelete}> delete</button>
<span>{props.todo.text}</span>
</li>
)
class App extends React.Component {
constructor() {
super()
this.state = {
todos: [],
}
}
addTodo() {
const text = prompt("TODO TEXT PLEASE!")
this.setState({
todos: [...this.state.todos, {id: id++, text: text, checked: false},
]
})
}
removeTodo(id) {
this.setState({
todos: this.state.todos.filter(todo => todo.id !== id )
})
}
toggleTodo(id) {
this.setState({
todos: this.state.todos.map(todo => {
if (todo.id !== id) return todo
return {
id: todo.id,
text: todo.text,
checked: !todo.checked,
}
})
})
}
render() {
return (
<div>
<div> Todo Count: {this.state.todos.length}</div>
<div> Unchecked Count: {this.state.todos.filter(todo => !todo.checked).length} </div>
<div className="App">
<label> Task Name:</label>
<input type="text" id="task"
/* onChange={(e)=> {
setTaskName(e.target.value);*/
/>
<button onClick={() => this.addTodo()}> Add ToDo </button>
</div>
<ul>
{this.state.todos.map(todo => (
<Todo
onToggle={() => this.toggleTodo(todo.id)}
onDelete={() => this.removeTodo(todo.id)}
todo={todo}
/>
))}
</ul>
</div>
)
}
}
To resolve this issue you are having, you will need to also add a local state to store your input field data (you could get this with a Controlled or Uncontrolled approaches):
this.state = {
currentTodo: "",
todos: [],
}
And then in your input onChange event as you already did (you were using a hook based approach though), you could add a state update for your currentTodo value as you write. And also the current state value in the input tag (as Cesare observed):
<input type="text" id="task"
value={this.state.currentTodo}
onChange={(e)=> {
this.setState({ ...this.state, currentTodo: e.target.value});
}
/>
Finally, to obtain the wroten text you can get it in your addTodo method.
const text = this.state.currentTodo;