Chapter 21 New data in case TodoList

In the previous section, we have completed the dynamic display of data, and now we have to complete the dynamic addition of data. How to add it? It must be added through the Header component, but how does the Header component hand over the collected task data to the App component and update the status? What about data?

Collect task item data in the Header component

import React, {
    
     Component } from 'react'
import "./index.css"
export default class Header extends Component {
    
    

  // 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    console.log(event.target.value)
  }

  render() {
    
    
    return (
      <div className="todo-header">
          <input onKeyUp={
    
    this.getTodoData} type="text" placeholder="请输入你的任务名称,按回车键确认"/>
      </div>
    )
  }
}

We addedonKeyUpkeyboard event on the input box element of the component. Because the event occurs in the element itself, we don't need toref, but pass The event source gets the input data.

Modification 1: We want to print the data we collected whenenter(回车键) is pressed

  // 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    const {
    
    keyCode,target} = event
    if (keyCode === 13) {
    
    
      console.log(target.value,keyCode)
    }   
  }

We can get keyCode 和 target from the event to confirm whether the Enter key was pressed and the collected value. But there is a problem here: when the input box has no value, pressing the Enter key can also print the value, which is not what we want.

Transformation 2: Null values ​​do not handle subsequent logic

  // 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    const {
    
    keyCode,target} = event
    if (target.value.trim() === '') return;
    if (keyCode === 13) {
    
    
      console.log(target.value,keyCode)
    }
  }

When we determine that the value of the input box is empty and the Enter key is pressed, we directlyreturn do not perform subsequent processing.

Transformation 3: Assemble the entered task name into a Todo object

  // 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    const {
    
    keyCode,target} = event
    if (target.value.trim() === '') return;
    if (keyCode === 13) {
    
    
      const newTodoObj = {
    
    id:'004',name:target.value,done:false}
      console.log(newTodoObj)
    }
  }

Here we assemble the input values ​​​​we get into an object to prepare for the follow-up, but there is a problem here, that is idThe value is 004, This is a fixed value. Of course, it is no problem if we only add one piece of data, but we must add more than one piece of data, because that would be meaningless.

Transformation 4: Change the ID value into a unique identifier without duplication

Here we need to installnanoidUsing this library we can generate unique onesuuid

Step 1: Install dependencies

npm i nanoid

Step 2: Introduce dependencies and transform the code

import {
    
     nanoid } from 'nanoid'  

// 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    const {
    
    keyCode,target} = event
    if (target.value.trim() === '') return;
    if (keyCode === 13) {
    
    
      const newTodoObj = {
    
    id:nanoid(),name:target.value,done:false}
      console.log(newTodoObj)
    }
  }

Step 3: Check the effect

 { id: "v1NnCpyHxlh4qrKwlv2W1", name: "45151", done: false }

We can see that id here has become a string of length 21, each time the method nanoid() will generate a non-repeating string with a default length of 21.


Pass the collected data to the App component

How do we pass the collected data to theApp component? The answer is againprops. But theprops passed this time is a function, not an ordinary value.

Insert image description here


  • Step 1: Define a function in the App component and use props to pass in the Header component.
import React, {
    
     Component } from 'react'
import Header from "./components/Header"
import List from "./components/List"
import Footer from "./components/Footer"
import "./index.css"

export default class App extends Component {
    
    
  // 定义列表的初始状态数据
  state = {
    
    todos: [
    {
    
    id:'001',name:'吃饭',done: true},
    {
    
    id:'002',name:'睡觉',done: true},
    {
    
    id:'003',name:'写代码',done: false},
  ]}

  // 获取Header组件收集的任务项数据
  addTodo = (todoObj) => {
    
    
    console.log(todoObj)
  }

  render() {
    
    
    const {
    
     todos } = this.state
    return (
      <div className="todo-container">
      <div className="todo-wrap">
        <Header addTodo={
    
    this.addTodo}/>
        <List todos={
    
    todos}/>
        <Footer/>
      </div>
    </div>
    )
  }
}
  • Step 2: The Header component passes the assembled object as a parameter through the addTodo function
  // 收集输入的任务项数据
  getTodoData = (event) => {
    
    
    const {
    
    keyCode,target} = event
    if (target.value.trim() === '') return;
    if (keyCode === 13) {
    
    
      const newTodoObj = {
    
    id:nanoid(),name:target.value,done:false}
      this.props.addTodo(newTodoObj)
      target.value = '' // 清空输入框
    }
  }
  • Step 3: Update the state data of the App component
  // 获取Header组件收集的任务项数据
  addTodo = (todoObj) => {
    
    
    const {
    
     todos } = this.state
    const newTodo = [todoObj, ...todos]
    this.setState({
    
    todos:newTodo})
  }

Here we get the old status data and assemble it with the data collected by the Header component, and use setState to update the status, because the page will be re-rendered , so the List component also gets the latest data.


Summary

In this section, you mainly learn the following knowledge:

  • UsekeyCode attribute to determine the Enter key
  • UsenanoidDependency library generationUUID
  • Useprops to pass the function so that the parent component can get the data of the child component

Guess you like

Origin blog.csdn.net/qq_36362721/article/details/129882007