随着你的应用程序的增长,它变得更有可能遇到意外的行为和错误;其中一些问题可以通过使用JavaScript的扩展来克服,比如Flow或TypeScript,这将有助于在编译时对整个应用程序进行类型检查。
然而,对于JavaScript React项目来说,除了这两个工具之外,还有一个更重要的工具,它有助于故障排除过程,这就是PropTypes。
介绍一下PropTypes
PropTypes是一个库,它提供了某些实用工具,用于记录被传递给组件的属性类型。
PropTypes工具曾经是React核心模块的一部分,现在作为一个独立的库暴露在**npm注册表**下,它被称为 [prop-types](https://www.npmjs.com/package/prop-types).
安装
为了安装这个包,你所要做的就是根据你选择的软件包管理器运行以下命令:
保护我们的props
现在我们已经成功地安装了这个库,我们可以在一个未命名的导入下导入它的所有工具,在我们的例子中,它将被称为PropTypes ,这是一个明确的名称。
导入的实用程序基本上由类型和方法组成,允许我们将组件的道具塑造成某些静态或动态对象、数组等。
然而,为了将这些类型与组件本身联系起来,我们将把类型的保障对象分配给组件的propTypes 属性。
PropTypes将处理所有的动态属性和引擎盖下的链接,所以也有一点神奇的地方。
至于一切是如何捆绑在一起的,我们可以看看下面的例子:
import PropTypes from 'prop-types';
const User = ({ name, surname, age }) => {
return (
<div>
<p>Name: {name}</p>
<p>Surname: {surname}</p>
<p>Age: {age}</p>
</div>
)
}
export default User;
User.propTypes = {
name: PropTypes.string,
surname: PropTypes.string,
age: PropTypes.number
};
我们创建了一个User ,该组件期望有3个道具。name,surname, 和age 。然后我们将这些渲染到屏幕上,展示一些相关的用户信息。
而且,正如你可能已经注意到的,我们也使用PropTypes来验证我们期望的每个道具的类型。我们期望 **name**和 **surname**类型为string ,而 age类型为number 。让我们移到App.js,看看如何使用我们的新组件
import User from './User'
function App() {
return (
<div style={{ margin: '50px' }}>
<h1>Current User:</h1>
<User name="Tommy" surname="Smith" age={23} />
</div>
);
}
export default App;
在App.js中,我们只是在JSX中使用用户并传递相关的props。让我们看看我们的应用程序是什么样子的。

干得好!看起来一切都像它应该的那样工作。没有任何错误。
如果我们在传递道具时犯了一个错误,因为我们没有注意而把年龄和姓氏对调了呢?
import User from './User'
function App() {
return (
<div style={{ margin: '50px' }}>
<h1>Current User:</h1>
<User name="Tommy" surname={23} age="Smith" />
</div>
);
}
export default App;

由于PropTypes的存在,这个问题被发现了
我们可以看到,PropTypes检测到我们向道具传递了错误的类型,然后它抛出了一个错误,我们可以注意到它被记录到了控制台。
通过捕捉这样的错误,我们能够建立更可预测的应用程序。
然而,我们并不局限于字符串和数字;既不作为实际的类型,也不作为类型选项;我们可以根据自己的喜好对它们进行建模,不管它们是对象、函数、数组,甚至是这三种类型中的任何一种。
例如,我们可以有一个组件,接收一个数字或字符串的数组,并将它们渲染到屏幕上。
import React from 'react';
import PropTypes from 'prop-types';
const Renderer = ({ itemsToRender }) => {
return (
<ul>
{itemsToRender?.map((itemToRender) => (
<li>{itemToRender}</li>
))}
</ul>
);
};
Renderer.propTypes = {
itemsToRender: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])),
};
export default Renderer;
让我们试着在App 组件中导入并使用我们的组件,而不给它任何参数,看看接下来会发生什么。
import './App.css';
import Renderer from './components/Renderer';
function App() {
return (
<div className="App">
<Renderer />
</div>
);
}
export default App;
正如预期的那样,如果我们尝试启动我们的服务器并打开我们的浏览器,控制台中会出现以下内容。

应用错误
现在,让我们试着把一些无效的数据传给Renderer 组件,看看会发生什么。
import './App.css';
import Renderer from './components/Renderer';
function App() {
const itemsToRender = [
'Sunday',
15,
23,
true
];
return (
<div className="App">
<Renderer itemsToRender={itemsToRender} />
</div>
);
}
export default App;


应用程序的当前状态
该应用程序似乎正在做它以前做的事情,那就是显示它可能收到的任何数值。然而,当遇到第4个值时,我们的应用程序向我们抛出了一个警告,关于没有正确的props。
你可以在这里找到更多的例子。
你必须记住,来自PropTypes的问题不会中断应用程序的正常流程,而是在开发经验中提供帮助。
与TypeScript的用法
虽然看起来它们做的是同一件事,但实际上它们之间没有任何重叠;TypeScript提供编译时覆盖,而PropTypes提供运行时覆盖。
不仅如此,它们的目的也完全不同:
- TypeScript在编写代码时很有用,因为它将警告你无效的参数或道具,以及帮助你使用自动完成功能。
- PropTypes在测试组件如何与不同的数据交互时很有用,也有助于测试下降的组件及其失败的原因。
在第一次处理每种技术时,这是一个常见的问题,但答案是,你可以同时使用这两个库,甚至可能被推荐这样做,因为它允许在你的应用程序中获得更高的安全性和可预测性。
如果你想了解更多关于TypeScript和TypeScript在React应用中的使用,请务必查看**这**篇文章。
总结
在这篇文章中,我们已经了解了什么是PropTypes库,它为我们提供了哪些工具,如何使用这些工具,以及回答了它与TypeScript一起使用是否多余的问题(其实不然)。
我希望你喜欢这个阅读,并且能够在理解这个库是什么以及如何使用它时获得一些有洞察力的信息。
如果你觉得我遗漏了什么,或者我对这个库的某个方面关注不够,请在下面留言,我们会非常感谢你的反馈并加以考虑。
在下一次会议上见。干杯!