如果你在过去的 12 个月里使用过 React Native,那么你可能已经使用 PropTypes 作为检查你的组件类型的一种手段。类型检查是一种保护你的组件并确保它们被正确使用的方式。
虽然使用 PropTypes 来对你的组件进行类型检查没有任何问题,但你可能已经注意到,使用 React Native 内置的 PropTypes
,如 ViewPropTypes
,会出现一个弃用警告。
在这篇文章中,我们将深入探讨为什么会出现这种弃用情况以及如何解决这个问题。
什么是 React Native PropTypes?
很长一段时间里,PropTypes
是 React Native 提供的开箱即用的解决方案,看起来像下面这样:
import React from 'react' import { View, ViewPropTypes } from 'react-native' import PropTypes from 'prop-types' export const Component = props => return ( <View style={{ alignSelf: 'center' }}> <View style={[styles.innerView, { backgroundColor: props.backgroundColor }]} /> <SomeOtherComponent /> </View> ) } Component.propTypes = { numberProp: PropTypes.number, boolProp: PropTypes.bool, arrayProp: PropTypes.array.isRequired, stringProp: PropTypes.string.isRequired, backgroundColor: ViewPropTypes.style, }
如上所述,这现在会导致一个错误消息:
ERROR Invariant Violation: ViewPropTypes has been removed from React Native. Migrate to ViewPropTypes exported from 'deprecated-react-native-prop-types'.
弃用 PropTypes
在 React Native 之前,React 本身也从 PropTypes 转向了外部类型检查器,如 Flow 和 TypeScript。要理解 React Native 为何做出这种转变,了解其历史背景会很有帮助。
在不深入所有细节的情况下,React Native 团队确认了这种变化的两个主要原因:更严格的类型安全性和编译时验证。
使用 PropTypes 可以在运行时验证你的组件,这意味着代码需要在类型检查生效之前运行。这就是为什么你只能在启动应用程序的开发服务器并在控制台中看到验证警告的原因。
除此之外,使用 PropTypes 创建类型的 API 相当有限,主要涵盖原始类型,几乎不涵盖更复杂的数据类型。
像 Flow 和 TypeScript 这样的工具被称为静态类型检查器,它们在编译时检查类型,这意味着不需要运行任何代码进行验证。这意味着你的组件可以在任何时刻进行类型检查——甚至在持续集成中——而不会产生太多开销。这两种选项也都有更广泛的 API,为你的应用程序提供更严格和更安全的类型定义。
由于这些原因,React Native 从 2018 年开始了弃用过程。最后,在 0.68 版本中,添加了一个弃用警告,以通知库用户即将发生的这个变化。
2022 年 6 月几个月后,所有的 PropTypes 都从 React Native 0.69 中移除,并转移到另一个包,这导致了之前显示的弃用错误。
如何解决 PropTypes 弃用问题
虽然你现在知道 PropTypes 何时以及为什么被弃用,但这并不能解决手头的错误。一般来说,有三种不同的社区方法来解决这个问题,以及 React Native 团队自己的推荐。
修补 React Native
社区最常采用的选择是最直接的一种:使用类似 patch-package
的东西来修补 React Native 库。基本上,这就归结为改变现有库的代码,以重新添加被移除的 PropTypes,使你的现有代码再次工作。
虽然这在社区中是一个受欢迎的解决方案,但 React Native 团队对此并不太支持。修补库最终只是掩盖了潜在的问题以获得短期收益,这可能对你的项目的长期可维护性产生重大影响。因此,从理论上讲,这也是最不受欢迎的解决方案。
这并不意味着应该绝对禁止打补丁。实际上,React Native 团队也表示,当使用 React Native 的库还没有移除他们的 PropTypes 用法时,有时候打补丁是必要的。
但即使在这些情况下,如果库方面还未修复,你应该把修补你这边的库作为最后的手段。
使用新的库
第二个解决方案是遵循弃用警告的建议,这意味着安装并使用新创建的 deprecated-react-native-prop-types 库。这个包含所有被弃用和移除的 PropTypes,但是被 React Native 团队移到了一个新的,独立的位置。
使用新库需要你更新所有的 PropTypes 导入,并确保它们指向新的位置,而不是之前的 react-native
。在简单的情况下,搜索和替换应该能够解决这个问题。
‘
然而,如果你的情况更复杂,例如,从 react-native
导入大文件和多种类型的代码,那么这种方法可能不适合你。在这些情况下,你应该寻求一个代码修改工具,或者自己创建一个。
类似于修补 React Native,这仍应被视为临时解决方案。虽然这是一个简单的解决方案,可能会受到大部分社区的青睐,但它再次更像是权宜之计,而非长期解决方案。
切换到合适的类型系统
最佳的解决方案,也是 React Native 核心维护者 Ricky Hanlon 推荐的方案,是切换到适当的类型系统。正如我们在本文前面讨论的那样,运行时类型系统能为你做什么存在缺点和局限性。
从长期来看,你会从静态类型检查器中看到显著的、长期的可维护性好处。至于这个类型检查器是 TypeScript 还是 Flow,那就取决于你,因为这两者都是完全合适的选择。
目前,TypeScript 无疑是这个领域最受欢迎的选择。然而,真的没有什么糟糕的选择。最终,最重要的是从运行时类型检查系统转向静态类型检查系统。
显然,这个解决方案不仅有好处,否则社区会一致倾向于这个。在这个特定的情境下,这个解决方案的主要缺点是所需的努力量。
总结
弃用 PropTypes 是 React Native 团队鼓励社区向静态类型检查器如 Flow 和 TypeScript 转变的一步,这些检查器相较于运行时类型检查器如 PropTypes,具有几个关键优势。
具体来说,他们提供了更严格的类型安全性,更快的类型验证,以及更广泛的选项来验证你的代码并允许类型检查集成到 CI/CD 中 – 所有这些都对你的项目代码的可维护性和开发产生了积极的长期影响。