javascript - 如何为 React 待办事项应用添加完整的功能?

标签 javascript reactjs

我使用 This tutorial 创建了一个待办事项应用程序。我需要修改功能完整的待办事项列表应用程序。如何为该应用程序添加完整的功能?这意味着“正在完成添加的项目。应该通过交叉相应的已完成项目来显示”。

这些是我在 src 文件夹中的屏幕。

这是我的 App.js 文件。

import React, { Component } from 'react'
import TodoInputs from './components/TodoInputs';
import TodoList from './components/TodoList';

import "bootstrap/dist/css/bootstrap.min.css";
import { v4 as uuidv4 } from 'uuid';

class App extends Component {
  state={
    items:[],
    id:uuidv4(),
    item:"",
    editItem:false
  }
  handleChange = e =>{
    this.setState({
      item:e.target.value
    });
  };
  handleSubmit = e =>{
    e.preventDefault();

    const newItem = {
      id:this.state.id,
      title:this.state.item
    }
// console.log(newItem);
    const updateItems = [...this.state.items,newItem];

    this.setState({
      items:updateItems,
      item:"",
      id:uuidv4(),
      editItem:false

    });
  };
  clearList =() =>{
    this.setState({
      items:[],
    });
  }
  handleDelete =(id) =>{
    const filteredItems = this.state.items.filter(item =>item.id !== id);
    this.setState({
      items:filteredItems
    });
  }
  handleEdit =(id) =>{
    const filteredItems = this.state.items.filter(item =>item.id !== id);
    const selectedItem = this.state.items.find(item => item.id === id);

    this.setState({
      items:filteredItems, 
      item:selectedItem.title,
      editItem:true,
      id:id
    });
  }
  handleComplete =(id) =>{
    const filteredItems = this.state.items.filter(item =>item.id !== id);
    const selectedItem = this.state.items.find(item => item.id === id);

    this.setState({
      items:filteredItems, 
      item:selectedItem.title,
      editItem:true,
      id:id
    });
  }
  render() {
    return (
      <div className= "container">
      <div className= "row">
         <div className= "col-10 mx-auto col-md-8 mt-4"> 
           <h3 className="text-capitalize text-center">todo App</h3>
           <TodoInputs item={this.state.item}
           handleChange={this.handleChange}
           handleSubmit={this.handleSubmit}
           editItem={this.state.editItem}/>
           <TodoList 
           items={this.state.items} 
           clearList={this.clearList} 
           handleDelete={this.handleDelete}
           handleEdit={this.handleEdit}
           handleComplete = {this.handleComplete}
           />
          </div>
      </div>
    </div>
    )
  }
}
export default App;

src文件夹内有一个文件夹“component”。以下文件位于组件文件夹内。

这是 TodoInputs.js 文件。

import React, { Component } from 'react';   

export default class TodoInputs extends Component {

    render() { 
        const {item,handleChange,handleSubmit,editItem} = this.props
        return (

            <div className="card card-body my-3">
                <form onSubmit={handleSubmit}>
                <div className="input-group"> 
                <div className="input-group-prepend">
                <div className="input-group-text bg-primary text-white">
                    <i className="fas fa-clipboard-list"></i>
                </div>
                </div>
                <input type="text" className="form-control" 
                placeholder="add todo item" 
                value={item} 
                onChange={handleChange}/>
                </div>
                <button type="submit" className={editItem ? "btn btn-block btn-success mt-3": "btn btn-block btn-primary mt-3"}>
                   {editItem ? "Edit Item": "Add Item"}
                </button>
                </form>
            </div>
          )
    }
}

这是 TodoItems.js 文件。

import React, { Component } from 'react';

export default class TodoItem extends Component {
    render() {
        const {title,handleDelete,handleEdit,handleComplete} = this.props
        return (
            <li className="list-group-item text-capitalize d-flex justify-content-between my-2">
               <h6>{title}</h6> 
               <div className="todo-icon">
               <span className="mx-2 text-success" onClick={handleComplete}>
                       <i className="fas fa-check"></i>
                   </span>
                   <span className="mx-2 text-warning" onClick={handleEdit}>
                       <i className="fas fa-pen"></i>
                   </span>
                   <span className="mx-2 text-danger" onClick={handleDelete}>
                       <i className="fas fa-trash"></i>
                   </span>
               </div>
            </li> 
        )
    }
}

这是 TodoList.js 文件。

import React, { Component } from 'react';
import TodoItem from './TodoItem';

export default class TodoList extends Component {
    render() {
        const {items,clearList,handleDelete,handleEdit,handleComplete}=this.props
        return (
            <ul className="list-group my-5">
                <h3 className="text-capitalize text-center">todo List </h3> 
                {items.map(item =>{
                    return <TodoItem 
                    key={item.id} 
                    title={item.title}
                    handleDelete={()=>handleDelete(item.id)}
                    handleEdit={()=>handleEdit(item.id)}
                    handleComplete={()=>handleComplete(item.id)}
                    />;   

                })}

                <button type="submit" className="btn btn-danger btn-block text-capitalize mt-5" onClick={clearList}>Clear List</button>
            </ul>
        )
    }
}

Here is a sample screen

最佳答案

现场演示:https://stackblitz.com/edit/react-krn81w

在 App.js 中,这些方法已更改:

handleSubmit = e =>{
    e.preventDefault();

    const newItem = {
      id:this.state.id,
      title:this.state.item,
      completed:false,
    }
// console.log(newItem);
    const updateItems = [...this.state.items,newItem];

    this.setState({
      items:updateItems,
      item:"",
      id:uuidv4(),
      editItem:false

    });
  };


handleComplete = (id) => {    
    this.setState( previousState => {
      //get previous items:
      let newItems = [...previousState.items];//this means the same as: let items=this.state.items.slice(0);
      //get index of clicked item
      let indexOfSelectedItem = previousState.items.findIndex(item => item.id === id);
      // change to cross it or not. If you want to cross it only once then write:
      // newItems[indexOfSelectedItem].completed = true;
      newItems[indexOfSelectedItem].completed = !previousState.items[indexOfSelectedItem].completed;

      return {
        items: newItems, 
      }
    })
  }

TodoList.js 看起来像这样:

import React, { Component } from 'react';
import TodoItem from './TodoItem';

export default class TodoList extends Component {
    render() {
        const {items,clearList,handleDelete,handleEdit,handleComplete}=this.props
        return (
            <ul className="list-group my-5">
                <h3 className="text-capitalize text-center">todo List </h3> 
                {items.map(item =>{
                    return <TodoItem 
                    key={item.id} 
                    title={item.title}
                    completed={item.completed}
                    handleDelete={()=>handleDelete(item.id)}
                    handleEdit={()=>handleEdit(item.id)}
                    handleComplete={()=>handleComplete(item.id)}
                    />;   

                })}

                <button type="submit" className="btn btn-danger btn-block text-capitalize mt-5" onClick={clearList}>Clear List</button>
            </ul>
        )
    }
}

和 TodoItem.js:

import React, { Component } from 'react';

export default class TodoItem extends Component {
    render() {
        const {title,completed,handleDelete,handleEdit,handleComplete} = this.props
        return (
            <li className="list-group-item text-capitalize d-flex justify-content-between my-2">
               <h6>{completed ? <del> {title} </del> : title}</h6> 
               <div className="todo-icon">
               <span className="mx-2 text-success" onClick={handleComplete}>
                       <i className="fas fa-check"></i>
                   </span>
                   <span className="mx-2 text-warning" onClick={handleEdit}>
                       <i className="fas fa-pen"></i>
                   </span>
                   <span className="mx-2 text-danger" onClick={handleDelete}>
                       <i className="fas fa-trash"></i>
                   </span>
               </div>
            </li> 
        )
    }
}

关于javascript - 如何为 React 待办事项应用添加完整的功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60867548/

相关文章:

javascript - 如何在没有代码 "editable = true"的情况下调整完整日历中的事件大小

reactjs - 使用 Typescript 进行 Formik 和 FieldArray 映射

reactjs - React Native 打开一个 Activity

php - 通过单击现有图像上传图像

javascript - 根据关键字对字符串进行分类

javascript - 如何在 javascript 中使用功能链接和组合?

javascript - 如何在 React 中更新我的帖子的评论

reactjs - WebStorm 自动补全不适用于 React js

javascript - React 导入前的 '@' 是什么意思?

javascript - 时间比较验证器