React 入门:实战案例 TodoList 对组件的 props 进行限制

news2024/11/20 0:46:23

文章目录

  • 安装 prop-types 库
  • 给组件的 props 添加限制
    • 给 Header 组件添加限制
    • 给 List 组件添加限制
    • 给 Item 组件添加限制
  • 验证 props 限制
  • 完整代码
    • Header 组件完整代码
    • List 组件完整代码
    • Item 组件完整代码

本文实现对组件的 props 进行属性的类型和必要性的限制。

为什么要对 props 增加限制呢?是为了在他人使用我们编写、或者我们使用他人编写的的组件的时候,传入了错误的 props 属性类型,或者漏传了必要的属性,通过限制可以在控制台报出有意义的错误提示信息。

建议: 在实际开发工作中,给组件编写必要性的注释,或者单独编写开发文档,介绍组件的使用,并说明 props 属性的类型和必要性。

安装 prop-types 库

PropTypes 提供一系列验证器,可用于确保组件接收到的数据类型是有效的。当传入的 prop 值类型不正确时,浏览器控制台将会显示警告。

  • 通过 npm 安装
npm install prop-types
  • 通过 yarn 安装
yarn add prop-types

注意:出于性能方面的考虑,propTypes 仅在开发模式下进行检查。

给组件的 props 添加限制

下面我们对 TodoList 的组件接收的 props 进行类型和必要性的限制。

给 Header 组件添加限制

Header 组件接收一个函数类型的 addTodo 的 props 属性,而且是必须的。实现代码片段如下:

// file: src/components/Header/index.jsx

// 引入 prop-types 库
import PropTypes from "prop-types";

// 以静态属性的方式定义限制规则
static propTypes = {
  addTodo: PropTypes.func.isRequired,
};

给 List 组件添加限制

List 组件接收以下两个 props 属性:

  • TodoList:数组类型,且必须。
  • updateTodo:函数类型,且必须。

实现代码片段如下:

// file: src/components/List/index.jsx

// 引入 prop-types 库
import PropTypes from "prop-types";

// 以静态属性的方式定义限制规则
static propTypes = {
  todoList: PropTypes.array.isRequired,
  updateTodo: PropTypes.func.isRequired,
};

给 Item 组件添加限制

Item 组件接收以下 props 属性:

  • id:数字类型,且必须。
  • name:字符串类型,且必须。
  • done:布尔类型,且必须。
  • updateTodo:函数类型,且必须。

实现代码片段如下:

// file: src/components/Item/index.jsx

// 引入 prop-types 库
import PropTypes from "prop-types";

// 以静态属性的方式定义限制规则
static propTypes = {
  id: PropTypes.number.isRequired,
  name: PropTypes.string.isRequired,
  done: PropTypes.bool.isRequired,
  updateTodo: PropTypes.func.isRequired,
};

至此我们就完成了对相关组件的 props 的限制。

扩展: 上面的代码只对 props 进行了简单的限制,如果你想要了解更多限制规则,请参考 React 官方介绍 使用 PropTypes 进行类型检查

验证 props 限制

下面我们以 Item 组件为例来验证上面添加的 PropTypes 限制是否起作用。

验证 id,它的限制规则是 数字且必须,那么我们把 App.js 中的初始化数据中的 id 改为字符串,代码如下:

// file: src/App.js

// 初始化状态
state = {
  todoList: [
    { id: 1, name: "参加晨会", done: true },
    { id: "2", name: "A功能开发", done: true }, // 将这条 todo 的 id 改为字符串
    { id: 3, name: "B功能开发", done: false },
  ],
};

此时浏览器控制台报错如下:
在这里插入图片描述

其他组件的验证,可按照上面的方法进行。

完整代码

Header 组件完整代码

// file: src/components/Header/index.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";
import { nanoid } from "nanoid";
import "./index.css";

export default class Header extends Component {
  // 对接收的 props 进行:类型、必要性的限制
  static propTypes = {
    addTodo: PropTypes.func.isRequired,
  };

  // 键盘事件的回调
  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>
    );
  }
}

List 组件完整代码

// file: src/components/List/index.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";
import Item from "../Item";
import "./index.css";

export default class List extends Component {
  // 对接收的 props 进行:类型、必要性的限制
  static propTypes = {
    todoList: PropTypes.array.isRequired,
    updateTodo: PropTypes.func.isRequired,
  };

  render() {
    const { todoList, updateTodo } = this.props;
    return (
      <ul className="todo-main">
        {todoList.map((todo) => {
          return <Item key={todo.id} {...todo} updateTodo={updateTodo} />;
        })}
      </ul>
    );
  }
}

Item 组件完整代码

// file: src/components/Item/index.jsx

import React, { Component } from "react";
import PropTypes from "prop-types";
import "./index.css";

export default class Item extends Component {
  // 对接收的 props 进行:类型、必要性的限制
  static propTypes = {
    id: PropTypes.number.isRequired,
    name: PropTypes.string.isRequired,
    done: PropTypes.bool.isRequired,
    updateTodo: PropTypes.func.isRequired,
  };

  state = { mouse: false }; //标识鼠标移入、移出

  // 鼠标移入、移出的回调
  handleMouse = (flag) => {
    return () => {
      this.setState({ mouse: flag });
    };
  };

  // 勾选、取消勾选某一个 Todo 的回调
  handleCheck = (id) => {
    return (event) => {
      this.props.updateTodo(id, event.target.checked);
    };
  };

  render() {
    const { id, name, done } = this.props;
    const { mouse } = this.state;
    return (
      <li
        style={{ backgroundColor: mouse ? "#eee" : "#fff" }}
        onMouseEnter={this.handleMouse(true)}
        onMouseLeave={this.handleMouse(false)}
      >
        <label className="container">
          <input
            type="checkbox"
            defaultChecked={done}
            onChange={this.handleCheck(id)}
          />
          <span>{name}</span>
        </label>
        <button
          className="btn btn-danger btn-sm"
          style={{ display: mouse ? "block" : "none" }}
        >
          删除
        </button>
      </li>
    );
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/82012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双十二买什么数码产品比较值?入手超值的数码好物盘点

2022年双十二正式开启倒计时模式&#xff0c;最近看到很多人问什么数码产品值得入手。现如今&#xff0c;数码产品已经贯彻在我们生活的方方面面&#xff0c;在此&#xff0c;我来给大家盘点几款入手超值的数码好物&#xff0c;可以当个参考。 一、蓝牙耳机 推荐产品&#xf…

JUC(6) : LockSupport | 优雅的线程通信工具

一、前言 前文介绍了 CompletableFuture 和 线程池的几种对线程的管理方式后&#xff0c;本质上&#xff0c;通过这些工具&#xff0c;可以直接帮我们对线程进行很好的管理和运作&#xff0c;什么时间需要启动哪个线程&#xff0c;以及线程的执行顺序等。毕竟&#xff0c;线程…

视频监控在油气长输管道巡护管理的应用解决方案

一、方案背景 由于油气产地与消费中心位置的不一致性&#xff0c;常常需要采用长距离的油气管道运输。从偏僻的矿区到繁华的街市&#xff0c;管道架设的环境十分复杂&#xff0c;一旦发生危险&#xff0c;后果将不堪设想。因此&#xff0c;为确保管道安全运行&#xff0c;消除…

redis高可用之主从复制,哨兵,集群

目录 前言 一、主从复制 1、主从复制的作用 2、主从复制流程 3、部署Redis 主从复制步骤 3.1 环境准备 3.2 首先要搭建redis&#xff0c;并关闭防火墙 3.3 修改Redis 配置文件(Master节点操作) 3.4 修改Redis 配置文件(Slave节点操作) 3.5 验证主从效果 二、哨兵 1…

App逆向案例 X嘟牛 - Frida监听 WT-JS工具还原(一)

App逆向案例 X嘟牛 - Frida监听 & WT-JS工具还原&#xff08;一&#xff09; 提示&#xff1a;文章仅供参考&#xff0c;禁止用于非法途径&#xff1b; 文章目录App逆向案例 X嘟牛 - Frida监听 & WT-JS工具还原&#xff08;一&#xff09;前言一、资源推荐二、App抓包分…

基于android平台的语音机器人服务娱乐系统

分 类 号&#xff1a;TP311 学校代码&#xff1a;11460 学 号&#xff1a;10130920 本科生毕业论文 基于android平台的语音机器人服务娱乐系统 Robot Entertainment Service System Based on Android Platform 所在系&#xff08;院&#xff09;&#xff1a; 学 生&…

如何通过快解析建设“智慧工地”,实现远程管理维护

A企业是我国某大型房地产企业&#xff0c;早在几年前就实现了全国化布局&#xff0c;目前除了住宅开发与销售、商用地产开发与销售及持有运营业务外&#xff0c;还涉猎房地产金融、物业服务与社区经营等领域。作为中国房地产的知名企业&#xff0c;从2020年起&#xff0c;A企业…

CentOS虚拟机搭建Hadoop集群

注&#xff1a;本文是对 https://www.bilibili.com/video/BV1CU4y1N7Sh 的实践。 环境 CentOS 7.7JDK 8Hadoop 3.3.0 准备 VMWare的网络设置&#xff1a;略。 准备好3台虚拟机&#xff0c;其IP地址分别为 192.168.88.151 、 192.168.88.152 、 192.168.88.153 &#xff0c…

RK3399 Android 8.1 开机动画制作全流程详解

文章目录一、开机动画包二、开机动画图片三、desc.txt编写规范四、开机动画临时生效五、开机动画内置系统一、开机动画包 N个文件夹和一个desc.txt。文件夹中是开机动画的图片资源&#xff0c;按照文件名顺序播放。desc.txt是开机动画的播放规范。压缩包必须是zip&#xff0c;…

力扣(LeetCode)1781. 所有子字符串美丽值之和(C++)

模拟 & 哈希集合 使用哈希集合&#xff0c;开字符集&#xff0c;下标对应小写字母顺序&#xff0c;值对应字符出现次数。 所有子字符串&#xff0c;根据示例看出&#xff0c;是连续子字符串。那么枚举起点&#xff0c;再枚举子字符串长度&#xff0c;就是所有连续子字符串…

web网页大作业:基于html设计与实现的茶文化网站12页(带psd)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

如何使用PyMySQL模块进行增删改查?

在正式动手之前&#xff0c;我们需要先安装 PyMySQL 模块。 &#xff08;1&#xff09;使用 pip 安装, 清华镜像&#xff1a; pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pymysql &#xff08;2&#xff09;使用 conda 安装 conda install pymysql Step2: …

毕业/课程设计——基于STM32的智能灯光控制系统(智能家居、手机APP控制、语音控制)

文章首先介绍本系统所包含的功能&#xff0c;主要包含六方面功能&#xff0c;之后逐步分享开发过程&#xff0c;其流程如下&#xff1a;点亮灯带&#xff08;三极管&#xff09;→调节灯光亮度&#xff08;PWM&#xff09;→为系统添加远程控制功能→为系统添加语音识别功能→添…

【脚本项目源码】Python实现鲁迅名言查询系统

前言 本文给大家分享的是如何通过利用Python实现鲁迅名言查询系统&#xff0c;废话不多直接开整~ 开发工具 Python版本&#xff1a; 3.6 相关模块&#xff1a; PyQt5模块 fuzzywuzzy模块 环境搭建 安装Python并添加到环境变量&#xff0c;pip安装需要的相关模块即可。 …

R语言使用最优聚类簇数k-medoids聚类进行客户细分

k-medoids聚类简介 k-medoids是另一种聚类算法&#xff0c;可用于在数据集中查找分组。k-medoids聚类与k-means聚类非常相似&#xff0c;除了一些区别。k-medoids聚类算法的优化功能与k-means略有不同。最近我们被客户要求撰写关于聚类的研究报告&#xff0c;包括一些图形和统…

【JavaWeb开发-Servlet】将项目部署在云服务器

目录 1、环境 &#xff08;1&#xff09;连接服务器 &#xff08;2&#xff09;安装JDK1.8​编辑 ①到官网下载环境 ②将压缩包上传至linux中 ③解压jdk压缩包 ④修改文件名 ⑤配置环境变量 &#xff08;3&#xff09;安装MySQL5.0 ①先下载MySQL的yum库 ②选择5.7发行版本…

基于C#+SQL Server(WinForm)学生选课及成绩查询管理系统【100010027】

学生选课及成绩查询管理系统的设计与开发 1、项目背景 学生选课及成绩查询系统是一个学校不可缺少的部分&#xff0c;传统的人工管理档案的方式存在着很多的缺点&#xff0c;如&#xff1a;效率低、保密性差等&#xff0c;所以开发一套综合教务系统管理软件很有必要&#xff…

Shell基础

获取命令结果$? 如果上一个命令是成功的则结果为0 否则为127 结果是 www.qfdu.com is down! EOF使用 sh 其实是bash的一个链接&#xff0c;本质上还是执行bash 然后脚本第一句表示使用什么执行器&#xff0c;如果写的是python但是你执行的时候不指定python会报错&#x…

Linux安装Mysql(图文解说详细版,安装包tar包版)

上次教大家用yum安装mysql https://blog.csdn.net/csdnerM/article/details/121095527&#xff0c; 结果还要小伙伴不知道tar包怎么安装&#xff0c;现在出个tar包安装的教程出来供大家参考 文章目录&#x1f3e2;1.官网下载tar包&#xff08;安装包&#xff09;&#x1f3e3;…

多个著名 Go 开源项目被放弃,做大开源不能用爱发电,更不能只靠自己!

大家好&#xff0c;我是煎鱼。相信关注我的许多同学都有接触 Go 语言的开发&#xff0c;甚至在企业中多有实践。那么你在日常开发中&#xff0c;势必会接触到 gorilla[1] 组织下的各个 Go 开源项目。如下图&#xff1a;gorilla/mux[2]&#xff1a;Star&#xff1a;17.9k。a pow…