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 addedonKeyUp
keyboard 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 id
The 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 installnanoid
Using 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.
- Step 1: Define a function in the
App
component and useprops
to pass in theHeader
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:
- Use
keyCode
attribute to determine the Enter key - Use
nanoid
Dependency library generationUUID
- Use
props
to pass the function so that the parent component can get the data of the child component