简体   繁体   中英

Is it possible to add Edit functionality to this Todo App made using ReactJS?

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>

编辑 lucid-sara-py8c7

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM