通过父子组件之间通信,使用 props
从父组件把一个函数传递到子组件中,然后子组件通过调用父组件传递进来的函数以参数的形式把子组件的数据传递给父组件。
在 App 组件中定义一个 addTodo
的组件方法,用来添加一条 Todo 记录,代码片段如下:
// src/App.js
/**
* addTodo 用于添加一条 Todo 记录,接收的参数是 Todo 对象
*/
addTodo = (todoObj) => {
// 获取原 TodoList
const { todoList } = this.state;
// 追加一条 Todo
const newTodoList = [todoObj, ...todoList];
// 更新状态
this.setState({ todoList: newTodoList });
};
通过 props
将 addTodo
传递到 Header 组件中,代码片段如下:
// src/App.js
<Header addTodo={this.addTodo} />
在 Header 组件中,通过触发 input 的 onKeyUp
事件,获取输入框的值,
然后通过调用 props
传进来的 addTodo
方法并将输入框的值作为参数传递到 App 组件中,
App 组件接收参数,并更新状态 state
,从而使得 List 数据列表的更新。
代码片段如下:
// src/components/Header/index.jsx
// 给 input 绑定 onKeyUp 事件
<input
onKeyUp={this.handleKeyUp}
type="text"
placeholder="请输入你的任务名称,按回车键确认"
/>;
// 定义 onKeyUp 事件的处理函数
handleKeyUp = (event) => {
// 解构赋值获取 keyCode, target
const { keyCode, target } = event;
// 判断是否是回车按键
if (keyCode !== 13) return;
// 添加的任务名称不能为空
if (target.value.trim() === "") {
alert("任务名称不能为空");
return;
}
// 构建一个 Todo 对象
const todoObj = { id: nanoid(), name: target.value, done: false };
// 将 todoObj 传递给 App 组件
this.props.addTodo(todoObj);
// 清空输入
target.value = "";
};
至此,完成了添加一条 Todo 到 TodoList 列表。
// file: src/App.js
import React, { Component } from "react";
import Header from "./components/Header";
import List from "./components/List";
import Footer from "./components/Footer";
import "./App.css";
export default class App extends Component {
// 初始化状态
state = {
todoList: [
{ id: 1, name: "参加晨会", done: true },
{ id: 2, name: "A功能开发", done: true },
{ id: 3, name: "B功能开发", done: false },
],
};
/**
* addTodo 用于添加一条 Todo 记录,接收的参数是 Todo 对象
*/
addTodo = (todoObj) => {
// 获取原 TodoList
const { todoList } = this.state;
// 追加一条 Todo
const newTodoList = [todoObj, ...todoList];
// 更新状态
this.setState({ todoList: newTodoList });
};
render() {
const { todoList } = this.state;
return (
<div className="todo-container">
<div className="todo-wrap">
<Header addTodo={this.addTodo} />
<List todoList={todoList} />
<Footer />
</div>
</div>
);
}
}
// file: src/components/Header/index.jsx
import React, { Component } from "react";
import { nanoid } from "nanoid";
import "./index.css";
export default class Header extends Component {
handleKeyUp = (event) => {
// 解构赋值获取 keyCode, target
const { keyCode, target } = event;
// 判断是否是回车按键
if (keyCode !== 13) return;
// 添加的任务名称不能为空
if (target.value.trim() === "") {
alert("任务名称不能为空");
return;
}
// 构建一个 Todo 对象
const todoObj = { id: nanoid(), name: target.value, done: false };
// 将 todoObj 传递给 App 组件
this.props.addTodo(todoObj);
// 清空输入
target.value = "";
};
render() {
return (
<div className="todo-header">
<input
onKeyUp={this.handleKeyUp}
type="text"
placeholder="请输入你的任务名称,按回车键确认"
/>
</div>
);
}
}
扩展
Header 组件中引入了一个扩展nanoid
用来生成一个唯一的 id 字符串,来作为 Todo 记录的唯一标识。
安装命令:yarn add nanoid
或者npm install nanoid
至此完成添加一条 Todo 记录到 TodoList 列表。