React.js 小书 Lesson24 - PropTypes 和组件参数验证
- 作者:胡子大哈
- 原文链接:http://huziketang.com/books/react/lesson24
- 转载请注明出处,保留原文链接和作者信息。
我们来了到了一个非常尴尬的章节,很多初学的朋友可能对这一章的知识点不屑一顾,觉得用不用对程序功能也没什么影响。但其实这一章节的知识在你构建多人协作、大型的应用程序的时候也是非常重要的,不可忽视。
都说 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 就会是 undefined,comment.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,有时候有点麻烦,但是是值得的。
因为第三方评论工具有问题,对本章节有任何疑问的朋友可以移步到 React.js 小书的论坛 发帖,我会回答大家的疑问。
React.js 小书 Lesson24 - PropTypes 和组件参数验证的更多相关文章
- 【React.js小书】动手实现 React-redux(五):Provider - 方志
我们要把 context 相关的代码从所有业务组件中清除出去,现在的代码里面还有一个地方是被污染的.那就是 src/index.js 里面的 Index: 1234567891011121314151 ...
- React.js 小书 Lesson22 - props.children 和容器类组件
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson22 转载请注明出处,保留原文链接和作者信息. 有一类组件,充当了容器的作用,它定义了一种外层 ...
- React.js 小书 Lesson20 - 更新阶段的组件生命周期
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson20 转载请注明出处,保留原文链接和作者信息. 从之前的章节我们了解到,组件的挂载指的是将组件 ...
- React.js 小书 Lesson19 - 挂载阶段的组件生命周期(二)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson19 转载请注明出处,保留原文链接和作者信息. 这一节我们来讨论一下对于一个组件来说,cons ...
- React.js 小书 Lesson18 - 挂载阶段的组件生命周期(一)
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson18 转载请注明出处,保留原文链接和作者信息. 我们在讲解 JSX 的章节中提到,下面的代码: ...
- React.js 小书 Lesson8 - 组件的组合、嵌套和组件树
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson8 转载请注明出处,保留原文链接和作者信息. 继续拓展前面的例子,现在我们已经有了 Heade ...
- React.js 小书 Lesson7 - 组件的 render 方法
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson7 转载请注明出处,保留原文链接和作者信息. React.js 中一切皆组件,用 React. ...
- React.js 小书介绍
React.js 小书 Github 关于作者 这是一本关于 React.js 的小书. 因为工作中一直在使用 React.js,也一直以来想总结一下自己关于 React.js 的一些知识.经验.于是 ...
- React.js小书总结
(迁移自旧博客2017 08 27) 第一阶段 react的组件相当于MVC里面的View. react.js 将帮助我们将界面分成了各个独立的小块,每一个块就是组件,这些组件之间可以组合.嵌套,就成 ...
随机推荐
- CentOS下Docker与.netcore(四)之 三剑客之一Docker-machine+jenkins简单自动化部署
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客 ...
- C# 代码 获取桌面路径
Environment.GetFolderPath(Environment.SpecialFolder.MyComputer); // // 摘要: // 获取由指定枚举标识的系统特殊文件夹的路径. ...
- Java 访问修饰符使用规则
作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × 1. ...
- 来到cnblong dayone
以前懒得做笔记,csdn上有些小随笔,但是感觉csdn上的广告和积分下载越来越无法忍受了.现在转到cnblog.希望以后能够多写一些随笔吧.也算是一种坚持.听说90天可以养成一种习惯,那么就从现在开始 ...
- python之爬虫--番外篇(一)进程,线程的初步了解
整理这番外篇的原因是希望能够让爬虫的朋友更加理解这块内容,因为爬虫爬取数据可能很简单,但是如何高效持久的爬,利用进程,线程,以及异步IO,其实很多人和我一样,故整理此系列番外篇 一.进程 程序并不能单 ...
- easyui里面的API=====》 load
在easyui里面有个API load,这个API实用性质很强,可以直接帮我加载页面的数据到想需要的相应输入框里面,但是也要注意,这些将要被填入数据的输入框里面的属性有个要求:其中输入框里面的name ...
- XML标签属性
0. 内容索引 1. XML序列化与反序列化 2. 相关的常用Attribute 3. 相关的全部Attribute 4. XML序列化答疑 5. 高级议题 1. XML序列化与反序列化 // OBJ ...
- 简明依赖注入(Dependency Injection)
前言 这是因特奈特上面不知道第几万篇讲依赖注入(Dependency Injection)的文章,但是说明白的却寥寥无几,这篇文章尝试控制字数同时不做大多数. 首先,依赖注入的是一件很简单的事情. 为 ...
- POJ1591 M*A*S*H (JAVA)
这水题,真的坑 测试数据最后有空行,如果用sc.hasNextLine()判断,会RE 要改为sc.hasNext() 搞了我一上午,烦死 import java.util.*; public cla ...
- Beautiful Soup解析网页
使用前步骤: 1.Beautiful Soup目前已经被移植到bs4,所以导入Beautiful Soup时先安装bs4库. 2.安装lxml库:如果不使用此库,就会使用Python默认的解析器,而l ...