我们来了到了一个非常尴尬的章节,很多初学的朋友可能对这一章的知识点不屑一顾,觉得用不用对程序功能也没什么影响。但其实这一章节的知识在你构建多人协作、大型的应用程序的时候也是非常重要的,不可忽视。

都说 JavaScript 是一门灵活的语言 —— 这就是像是说“你是个好人”一样,凡事都有背后没有说出来的话。JavaScript 的灵活性体现在弱类型、高阶函数等语言特性上。而语言的弱类型一般来说确实让我们写代码很爽,但是也很容易出 bug。

变量没有固定类型可以随意赋值,在我们构建大型应用程序的时候并不是什么好的事情。你写下了 let a = {} ,如果这是个共享的状态并且在某个地方把 a = 3,那么 a.xxx 就会让程序崩溃了。而这种非常隐晦但是低级的错误在强类型的语言例如 C/C++、Java 中是不可能发生的,这些代码连编译都不可能通过,也别妄图运行。

大型应用程序的构建其实更适合用强类型的语言来构建,它有更多的规则,可以帮助我们在编写代码阶段、编译阶段规避掉很多问题,让我们的应用程序更加的安全。JavaScript 早就脱离了玩具语言的领域并且投入到大型的应用程序的生产活动中,因为它的弱类型,常常意味着不是很安全。所以近年来出现了类似 TypeScript 和 Flow 等技术,来弥补 JavaScript 这方面的缺陷。

React.js 的组件其实是为了构建大型应用程序而生。但是因为 JavaScript 这样的特性,你在编写了一个组件以后,根本不知道别人会怎么使用你的组件,往里传什么乱七八糟的参数,例如评论组件:

class Comment extends Component {
const { comment } = this.props
render () {
return (
<div className='comment'>
<div className='comment-user'>
<span>{comment.username} </span>:
</div>
<p>{comment.content}</p>
</div>
)
}
}

但是别人往里面传一个数字你拿他一点办法都没有:

<Comment comment={1} />

JavaScript 在这种情况下是不会报任何错误的,但是页面就是显示不正常,然后我们踏上了漫漫 debug 的路程。这里的例子还是过于简单,容易 debug,但是对于比较复杂的成因和情况是比较难处理的。

于是 React.js 就提供了一种机制,让你可以给组件的配置参数加上类型验证,就用上述的评论组件例子,你可以配置 Comment 只能接受对象类型的 comment 参数,你传个数字进来组件就强制报错。我们这里先安装一个 React 提供的第三方库 prop-types

npm install --save prop-types

它可以帮助我们验证 props 的参数类型,例如:

import React, { Component } from 'react'
import PropTypes from 'prop-types' class Comment extends Component {
static propTypes = {
comment: PropTypes.object
} render () {
const { comment } = this.props
return (
<div className='comment'>
<div className='comment-user'>
<span>{comment.username} </span>:
</div>
<p>{comment.content}</p>
</div>
)
}
}

注意我们在文件头部引入了 PropTypes,并且给 Comment 组件类添加了类属性 propTypes,里面的内容的意思就是你传入的 comment 类型必须为 object(对象)。

这时候如果再往里面传入数字,浏览器就会报错:

出错信息明确告诉我们:你给 Comment 组件传了一个数字类型的 comment,而它应该是 object。你就清晰知道问题出在哪里了。

虽然 propTypes 帮我们指定了参数类型,但是并没有说这个参数一定要传入,事实上,这些参数默认都是可选的。可选参数我们可以通过配置 defaultProps,让它在不传入的时候有默认值。但是我们这里并没有配置 defaultProps,所以如果直接用 <Comment /> 而不传入任何参数的话,comment 就会是 undefinedcomment.username 会导致程序报错:

这个出错信息并不够友好。我们可以通过 isRequired 关键字来强制组件某个参数必须传入:

...
static propTypes = {
comment: PropTypes.object.isRequired
}
...

那么会获得一个更加友好的出错信息,查错会更方便:

React.js 提供的 PropTypes 提供了一系列的数据类型可以用来配置组件的参数:

PropTypes.array
PropTypes.bool
PropTypes.func
PropTypes.number
PropTypes.object
PropTypes.string
PropTypes.node
PropTypes.element
...

更多类型及其用法可以参看官方文档: Typechecking With PropTypes - React

组件参数验证在构建大型的组件库的时候相当有用,可以帮助我们迅速定位这种类型错误,让我们组件开发更加规范。另外也起到了一个说明文档的作用,如果大家都约定都写 propTypes ,那你在使用别人写的组件的时候,只要看到组件的 propTypes就清晰地知道这个组件到底能够接受什么参数,什么参数是可选的,什么参数是必选的。

总结

通过 PropTypes 给组件的参数做类型限制,可以在帮助我们迅速定位错误,这在构建大型应用程序的时候特别有用;另外,给组件加上 propTypes,也让组件的开发、使用更加规范清晰。

这里建议大家写组件的时候尽量都写 propTypes,有时候有点麻烦,但是是值得的。

下一节:实战分析:评论功能(四)

上一节:dangerouslySetHTML 和 style 属性

PropTypes 和组件参数验证的更多相关文章

  1. React.js 小书 Lesson24 - PropTypes 和组件参数验证

    作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson24 转载请注明出处,保留原文链接和作者信息. 我们来了到了一个非常尴尬的章节,很多初学的朋友 ...

  2. 组件:参数验证props:组件参数验证语法

    <!DOCTYPE html> <html lang="zh"> <head> <title></title> < ...

  3. C# 中参数验证方式的演变

    一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型参数是否允许为空,如果是字符可能有长度限 ...

  4. C# 中参数验证方式

    C# 中参数验证方式 一般在写方法的时候,第一步就是进行参数验证,这也体现了编码者的细心和缜密,但是在很多时候这个过程很枯燥和乏味,比如在拿到一个API设计文档的时候,通常会规定类型参数是否允许为空, ...

  5. 4-3 组件参数校验与非props特性

    本文参考脚本之家,https://www.jb51.net/article/143466.htm 通过属性的形式,父组件对子组件进行参数的传递 //如下图: //父组件设置content属性,向属性中 ...

  6. SpringBoot08 请求方式、参数获取注解、参数验证、前后台属性名不一致问题、自定义参数验证注解、BeanUtils的使用

    1 请求方式 在定义一个Rest接口时通常会利用GET.POST.PUT.DELETE来实现数据的增删改查:这几种方式有的需要传递参数,后台开发人员必须对接收到的参数进行参数验证来确保程序的健壮性 1 ...

  7. Java和C#下的参数验证

    参数的输入和验证问题是开发时经常遇到的,一般的验证方法如下: public bool Register(string name, int age) { if (string.IsNullOrEmpty ...

  8. DUBBO参数验证

    public class ValidationParameter implements Serializable {           private static final long seria ...

  9. ASP.NET WebAPI 11 参数验证

    在绑定完Action的所有参数后,WebAPI并不会马上执行该方法,而要对参数进行验证,以保证输入的合法性. ModelState 在ApiController中一个ModelState属性用来获取参 ...

随机推荐

  1. 在C语言中使用libiconv进行编码转换的示例

    libiconv_sample.c #include <stdio.h> #include <malloc.h> #include "libiconv/iconv.h ...

  2. Ruby map、each、select、inject、collect 、detect reference

    参考 https://ruby-china.org/topics/26718 map:(collect是map的别名函数) 对数组中每个元素进行表达式操作,原始数组不会被改变,返回执行表达式结果的新数 ...

  3. BigDecimal快速使用

    double类型最多支持16位有效数字,且最大值只支持10^308次方,大一点的数字会变为科学计数法,小数精度不够等有一系列不方便的问题: 引进BigDecimal解决此类麻烦,弊端,BigDecim ...

  4. 字符串查找函数(BF)

    //模拟字符串定位函数 // s: abcbbghi // t: ghi // 返回6 #include <iostream> #include <string> #inclu ...

  5. Mysql语句示例

    Mysql语句示例 最常用 sql 语句总结 前言 Mysql 是数据库开发使用的主要平台之一.sql 的学习掌握与使用是数据库开发的基础,此处展示详细sql 语句的写法,及各种功能下的 sql 语句 ...

  6. JRE System Library 与Java EE Libraries的区别

    JRE System Library是只要做java开发都需要的完整的.标准的库.  Java EE5 Libraries只是java三个方向中做java EE所需要的库.如果做Web方面的开发的话就 ...

  7. oracle自动表分析

    oracle 表的统计信息,跟他的执行计划很有关联 执行计划的正常是否,跟SQL的执行速度很有关系 首先讲解一下如何查看一个数据库的是否开启自动统计分析 1.查看参数:STATISTICS_LEVEL ...

  8. 编译含有Servlet的java文件

    直接在命令行方式下用javac HelloWorld.java编译HellowWorld Servlet是不行的,因为Java SE JDK不含Servlet类库. 解决方法:在环境变量CLASSPA ...

  9. thiis also a test

    EL表达式 1.EL简介 1)语法结构 ${expression} 2)[]与.运算符 EL 提供.和[]两种运算符来存取数据. 当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号, ...

  10. JS按字节截取字符长度实例2

    /* * param str 要截取的字符串 * param L 要截取的字节长度,注意是字节不是字符,一个汉字两个字节 * return 截取后的字符串 */ function cutStr(str ...