React implements the addition, deletion, modification and query of todolist

React implements the addition, deletion, modification and query of todolist

Take todolist as an example

insert image description here

insert image description here

The directory is as follows

insert image description here

app.js

 import React, { PureComponent } from 'react'
import Input from './components/Input'
import List from './components/List'
import Total from './components/Total'
import Mask from './components/Mask'
import { bus as $bus } from './components/bus'
import './App.css'
export default class App extends PureComponent {
  constructor() {
    super()
    this.state = {
      flag: false,
      list: [
        {
          id: 1,
          content: 'Hahaha',
          checked: false
        },
        {
          id: 7,
          content: 'Hahaha',
          checked: false
        },
        {
          id: 5,
          content: 'Hahaha',
          checked: false
        },
      ],
      checkAll: false,
      selectLength: 0,
      item: {}
    }
  }
  // Select all or unselect all checkAllHandler(checked) {
    console.log("checked",checked);
    const { list } = this.state
    const newList = list.map(item =>{
      return {...item,checked}
    })
    this.setState({list:newList,checkAll:checked},()=>{
      this.doneLength()
    })
  }
  // Single-choice single-select checkHandler =(id,checked)=> {
    const { list } = this.state
    const newList = list.map(item => {
      return item.id === id ? {...item,checked} : item
    })
    let checkAll = newList.length && newList.every(item => item.checked)
    this.setState(() => ({list: newList,checkAll}),()=>{
      this.doneLength()
    })
  }
  // add addHandler = (obj)=>{
    let { list } = this.state;
    let newList = [...list,obj]
    console.log('newList===='+newList)
    this.setState({
      list: newList,
    },()=>{
      this.doneLength()
    })
  } 
  // Search searchHandler=(content)=>{
    console.log("content",content);
    let { list } = this.state;
    let newList = list.filter(item => item.content.includes(content))
    this.setState({
      list: newList
    },()=>{
      this.doneLength()
    })
  }
  // Delete delHandler = (id)=> {
    console.log("id",id);
    const { list } = this.state
    const newList = list.filter(item => item.id !=id)
    let checkAll = newList.length && newList.every(item => item.checked)
    this.setState(() => ({list: newList,checkAll}),()=>{
      this.doneLength()
    })
  }
  // Edit editHandler = (items)=>{
    this.setState({
      item: items
    })
  }
  // Update update = (content)=>{
    const { list,item } = this.state
    let obj = Object.assign(item,{content})
    const newList = list.map(v => {
      if(v.id === obj.id) {
        v = {...obj}
      }
      return v
    })
    this.setState({
      list: newList,
      item: obj
    })
  }
  // Completed doneLenth=()=> {
    const { list } = this.state
    const newList = list.filter(item => item.checked)
    let selectLength = newList.length
    setTimeout(()=>{
      this.setState({
        selectLength
      })
    })
  }
  // Mount componentDidMount() {
    this.unSubscribe = $bus.addListener("getFlag",(flag)=>{
      this.setState({flag})
    })
    this.unSubscribe1 = $bus.addListener("sendValue",(obj)=>{
     this.addHandler(obj)
    })
    this.unSubscribe2 = $bus.addListener("searchValue",(value)=>{
     this.searchHandler(value)
    })
    this.unSubscribe3 = $bus.addListener("getItem",(item)=>{
     this.editHandler(item)
    })
    this.unSubscribe4 = $bus.addListener("update",(content)=>{
     this.update(content)
    })
  }
  // Unmount componentWillUnmount() {
    $bus.removeListener(this.unSubscribe)
    $bus.removeListener(this.unSubscribe1)
    $bus.removeListener(this.unSubscribe2)
    $bus.removeListener(this.unSubscribe3)
    $bus.removeListener(this.unSubscribe4)
  }
  render() {
    let { flag, list,checkAll,selectLength } = this.state
    return (
      <div className='container'>
        {/* Input box*/}
        <Input></Input>
        {/* list */}
        <List list={list} checkHandler={this.checkHandler} delHandler={this.delHandler}></List>
        {/* Statistics */}
        <Total checkAllHandler={this.checkAllHandler.bind(this)} checkAll={checkAll} selectLength={selectLength}></Total>
        {/* Edit popup box */}
        { flag ? <Mask ></Mask> : ''}
      </div>
    )
  }
}

Input.js

import React, { Component } from 'react'
import { bus as $bus } from './bus'
export default class Input extends Component {
  constructor() {
    super()
    this.state = {
      value:""
    }
  }
  changeHandler = (e)=>{
    this.setState({
      value: e.target.value
    })
    console.log("this.state.value",this.state.value);
  }
  // add addHandler = ()=>{
    let { value } = this.state;
    let obj = {
      id: Date.now(),
      content: value,
      done: false
    }
    if(value) {
      $bus.emit("sendValue",obj)
    } else {
      console.log("Please enter")
    }
  }
  // Search searchHandler = ()=>{
    console.log("search");
    let { value } = this.state;
    if(!value) return console.log("Please enter");
    $bus.emit("searchValue",value)
  }
  render() {
    let { value } = this.state
    return (
      <>
        <div className="input">
          <input type="text" value={value} placeholder='Please enter your task name and press Enter to confirm' onInput={this.changeHandler}/>
          <button className="btn btn-success" onClick={this.addHandler}>Add</button>
          <button className="btn btn-primary" onClick={this.searchHandler}>Search</button>
        </div>
      </>
    )
  }
}

List.js

import React, { Component } from 'react'
import Item from './Item'
import PropTypes from 'prop-types'
export default class List extends Component {
  static propTypes = {
		list:PropTypes.array.isRequired,
	}
  render() {
    let { list,checkHandler,checkAllHandler,delHandler } = this.props;
    console.log("list",list);
    return (
      <ul className="task-list">
        {
          list.map(item => (<Item item={item} key={item.id} checkHandler={checkHandler} checkAllHandler={checkAllHandler} delHandler={delHandler}></Item>))
        }
      </ul>
    )
  }
}

Item.js

import React, { Component } from 'react'
import { bus as $bus } from './bus'
export default class Item extends Component {
  constructor(props) {
    super(props)
    this.state = {}
  }
  changeHandler = (id)=>{
    let { checkHandler } = this.props;
    return (e)=>{
      checkHandler(id,e.target.checked)
    }
  }
  removeHandler(){
    let { delHandler } = this.props;
    delHandler(arguments[0])
  }
  editHadnler = (item)=>{
    $bus.emit("getFlag",true)
    localStorage.setItem("obj",JSON.stringify(item))
    $bus.emit("getItem",item)
  }
  render() {
    let { item } = this.props;
    return (
      <li className="task-item">
        <input type="checkbox" checked={item.checked} onChange={this.changeHandler(item.id)}/>
        <div className="content">
          {item.content}
        </div>
        <button className={`btn btn-success ${!item.checked ? "d-none" : "d-block"}`} onClick={()=> this.editHadnler(item)}>Edit</button>
        <button className={`btn btn-danger ${!item.checked ? "d-none" : "d-block"}`} onClick={this.removeHandler.bind(this,item.id)}>Delete</button>
      </li>
    )
  }
}

Total.js

import React, { Component } from 'react'
export default class Total extends Component {
  constructor() {
    super()
    this.changeAllHandler = this.changeAllHandler.bind(this)
  }
  changeAllHandler(e) {
    let { checkAllHandler } = this.props
    checkAllHandler(e.target.checked)
  }
  render() {
    let { checkAll,selectLength } = this.props;
    return (
      <div className="task-done">
        <input type="checkbox" onChange={this.changeAllHandler} checked={checkAll}/>
        <p>Completed<span className="single-number">{selectLength}</span> All<span className="all-number">4</span></p>
      </div>
    )
  }
}

Mask.js (pop-up window)

import React, { Component } from 'react'
import { bus as $bus } from './bus'
export default class mask extends Component {
  constructor() {
    super()
    this.state = {
      value: ''
    }
  }
  closeMask = ()=>{ // Close the pop-up window$bus.emit("getFlag",false)
  }
  updateHandler = ()=>{
    $bus.emit("getFlag",false)
    $bus.emit("update",this.state.value)
  }
  onChange = (e) => {
    this.setState({
      value: e.target.value
    })
  }
  componentDidMount() {
    let obj = JSON.parse(localStorage.getItem("obj"))
    this.setState({
      value: obj.content
    })
  }
  render() {
    let { value } = this.state
    return (
      <div>
        <div className="mm-mask" >
        <div className="mm-modal">
          <div className="mm-title">
            <span className="mm-edit">Edit</span>
            <span className="mm-close" onClick={this.closeMask}>x</span>
          </div>
          <div className="mm-content">
            <input type="text" value={value} placeholder="Task name" onInput={this.onChange}/>
          </div>
          <div className="mm-box-btn">
            <div className="mm-update" onClick={this.updateHandler}>Update</div>
            <div className="mm-cancel" onClick={this.closeMask}>Cancel</div>
          </div>
        </div>
      </div>
      </div>
    )
  }
}

bus.js

 yarn add -D events
import { EventEmitter } from 'events'
export const bus = new EventEmitter() // Export bus instance

App.css

* {
  margin: 0;
  padding: 0;
}
input,button {
  outline: none;
  border: 0;
}
ul>li {
  list-style: none;
}
.container {
  width: 400px;
  height: 500px;
  margin: 10px auto auto;
  padding: 20px;
  box-sizing: border-box;
  color: #3333;
  border: 1px solid;
  overflow: hidden;
}
.input {
  width: 100%;
  height: 30px;
  display: flex;
}
input {
  width: 100%;
  height: 100%;
  border: 1px solid #e1e1e1;
  box-sizing: border-box;
  border-radius: 4px;
  padding: 0 10px;
}
input::placeholder {
  color: #e1e1e1;
}
input:focus {
  border: 1px solid #0096e6;
}
.task-list {
  width: 100%;
  display: flex;
  flex-flow: column wrap;
  margin-top: 10px;
}
.task-list li {
  display: flex;
  height: 40px;
  justify-content: center;
  align-items: center;
  padding: 0 10px;
  background-color: #eef0f4;
  margin-bottom: 10px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.task-list li input[type^="checkbox"] {
  width: 15px;
  height: 15px;
  border: 1px solid #e1e1e1;
  cursor: pointer;
  flex-shrink: 0;
}
.task-list li .content {
  flex: 1;
  margin-left: 10px;
}
.btn {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  height: 30px;
  justify-content: center;
  padding: 5px 10px;
  text-align: center;
  cursor: pointer;
  border-radius: 4px;
  color: #fff;
  letter-spacing: 2px;
  margin: 0 5px;
  box-sizing: border-box;
  font-size: 16px;
}
.btn-success {
  background-color: #0f0;
}
.btn-danger {
  background-color: #f00;
}
.btn-primary {
  background-color: #0096e6;
}
.task-done {
  width: 100%;
  height: 40px;
  line-height: 40px;
  display: flex;
  align-items: center;
  background-color: #eef0f4;
  padding-left: 10px;
  box-sizing: border-box;
  margin-top: 30px;
}
.task-done input {
  width: 15px;
  height: 15px;
  border: 1px solid #e1e1e1;
  cursor: pointer;
  flex-shrink: 0;
  margin-right: 10px;
}
.single-number {
  color: #333;
  margin-left: 5px;
}
.all-number {
  color: red;
  margin-left: 5px;
}
.mm-mask{
  position:fixed;
  top:0;
  left:0;
  right:0;
  bottom:0;
  background:rgba(0,0,0,0.5);
}
.mm-modal{
  width:350px;
  position:absolute;
  top:50%;
  left:50%;
  transform:translate(-50%,-50%);
  z-index:1000;
  background:#ffffff;
  border-radius:4px;
  color:#333333;
}
.mm-title {
  height:50px;
  line-height:50px;
  display:flex;
  justify-content:space-between;
  border-bottom:1px solid #e1e1e1;
  box-sizing:border-box;
  font-size:20px;
}
.mm-edit{
  text-indent:20px;
}
.mm-close{
  margin-right:20px;
  font-family:consals;
  cursor:pointer;
}
.mm-content{
  padding:0 20px;
  margin-bottom:20px;
}
.mm-content input{
  width:100%;
  height:30px;
  line-height:30px;
  text-indent:20px;
  border-radius:4px;
  margin-top:20px;
  border:1px solid #666;
  box-sizing:border-box;
}
.mm-content input:hover{
  border:1px solid #0096e6;
}
.mm-content input:last-child{
  text-indent:5px;
}
.mm-box-btn{
  display:flex;
}
.mm-update,.mm-cancel{
  width:80px;
  height:30px;
  line-height:30px;
  text-align: center;
  cursor:pointer;
  background:#0096e6;
  color:#ffffff;
  user-select:none;
  border-radius:4px;
  margin:0 20px 50px;
}
.mm-update{
  margin-right:10px;
}
.d-none {
  display: none;
}
.d-block {
  display: block;
}

Summarize

This article ends here. I hope it can be helpful to you. I also hope you can pay more attention to more content on 123WORDPRESS.COM!

You may also be interested in:
  • How to implement add, delete, modify and check step by step in spring-boot react
  • JS operation object array to achieve add, delete, modify and query example code
  • Detailed explanation of dynamic addition, deletion, modification and query of properties when converting Java objects to JSON
  • Detailed explanation of common additions, deletions, modifications and other properties of JavaScript arrays
  • JS implementation of array addition, deletion, modification and query operations example

<<:  Bootstrap 3.0 study notes for beginners

>>:  What is html file? How to open html file

Recommend

Detailed explanation of Tomcat core components and application architecture

Table of contents What is a web container? The Na...

10 reasons why Linux is becoming more and more popular

Linux has been loved by more and more users. Why ...

Vue implements drag progress bar

This article example shares the specific code of ...

What is the function and writing order of the a tag pseudo class

The role of the a tag pseudo-class: ":link&qu...

mysql5.7.21.zip installation tutorial

The detailed installation process of mysql5.7.21 ...

JavaScript to achieve a simple countdown effect

This article example shares the specific code of ...

Why does your height:100% not work?

Why doesn't your height:100% work? This knowl...

How to query and update the same table in MySQL database at the same time

In ordinary projects, I often encounter this prob...

Build a WebRTC video chat in 5 minutes

In the previous article, I introduced the detaile...

Implementation of Mysql User Rights Management

1. Introduction to MySQL permissions There are 4 ...

Two ways to correctly clean up mysql binlog logs

mysql correctly cleans up binlog logs Preface: Th...