I have created a Todo List app successfully to some extent. My constructor function of TodoList
is as follows:
class TodoList extends React.Component {
constructor(props) {
super(props);
this.state = { value: '',
todoList: [{ id: 1, content: "Call Client" },
{ id: 2, content: "Write Log" }] }
this.onChangeValue = this.onChangeValue.bind(this);
this.onAddItem = this.onAddItem.bind(this);
}
The remaining body of TodoList
has Add Item functionality, by using two methods onChangeValue
and onAddItem
onChangeValue = event => {
this.setState({ value: event.target.value });
};
onAddItem = () => {
if (this.state.value !== '') {
this.setState(state => {
const todoList = state.todoList.concat({ id: state.todoList.length + 1, content: this.state.value});
return {
todoList,
value: '',
};
});
}
};
render() {
const listItems = this.state.todoList.map((todo) =>
<ListItem key={todo.id} id={todo.id} content={todo.content}/>
)
return <>
<ul className="todo-list">
{listItems}
</ul>
{/* <AddItem/> */}
<div className="add-item">
<input type="text" onChange={this.onChangeValue}/>
<button type="submit" onClick={this.onAddItem}>Add Item</button>
</div>
</>
}
}
Delete functionality and Mark as read functionality are created in the ListItem
component using methods handleChange
and handleDeleteClick
.
class ListItem extends React.Component {
constructor(props) {
super(props);
this.state = { done : false, editing : '', deleted : false }
this.handleChange = this.handleChange.bind(this);
this.handleDeleteClick = this.handleDeleteClick.bind(this);
}
handleChange(event) {
this.setState({done: event.target.checked})
}
handleDeleteClick() {
this.setState({ deleted : true })
}
render() {
if (this.state.deleted === false) {
return <li className="list-item">
{/* special class is added to the paragraph to strike the text when marked as done */}
<p className={this.state.done ? 'done' : ''}>{this.props.content}</p>
<ul className="actions">
<li>
<label htmlFor={'item_' + this.props.id}>Mark as done</label>
<input name={'item_' + this.props.id} id={'item_' + this.props.id} type="checkbox" onChange={this.handleChange}/>
</li>
<li>
{/* Edit button is disabled once the task is marked as done */}
{ this.state.done ? <button type="button" disabled>Edit</button> : <button type="button">Edit</button> }
</li>
<li><button type="button" onClick={this.handleDeleteClick}>Delete</button></li>
</ul>
</li>
}
else {
return null;
}
}
}
Now the only thing remaining is the edit functionality which I cannot figure out if it's possible or not.
The source code of my application can be found in this codepen: https://codepen.io/blenderous/pen/rNeywyZ
We could create an onEditItem
method inside the TodoList
item and pass this method to each ListItem
. This method would receive an id
and a newContent
values to process the updates.
// TodoList component
...
onEditItem = (id, newContent) => {
const newTodoList = this.state.todoList.map((todo) => {
// return todo.id !== id ? todo : { ...todo, content: newContent }
// not same id? leave as is
if (todo.id !== id) {
return todo;
}
// update content with the newContent value
return { ...todo, content: newContent };
});
this.setState({ todoList: newTodoList });
};
Then on our ListItem
, we'll create an handleEditClick
method that will handle the click event for our edit button.
// ListItem component
...
handleEditClick() {
const { id, content } = this.props;
// prompt to edit the current content
const newContent = prompt("Edit:", content);
// call the TodoList editTodo passing the id and the new content
// of the current todo
this.props.editTodo(id, newContent);
}
Now we'll use this method on our edit button like so
...
<button
type="button"
disabled={this.state.done} // disabled once the task is marked as done
onClick={this.handleEditClick}
>
Edit
</button>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.