文章插图
本文将探究 React API 的演变及其背后的心智模型 。从 mixins 到 hooks,再到 RSCs,了解整个过程中的权衡 。我们将对 React 的过去、现在和未来有一个更清晰的了解,便于深入研究遗留代码库并评估其他技术如何采用不同的方法并做出不同的权衡 。
React API 简史我们从面向对象的设计模式在 JS 生态系统中流行的时候开始,可以在早期的 React API 中看到这种影响 。
MixinsReact.createClass API 是创建组件的原始方式 。在 JAVAscript 支持原生类语法之前,React 就有自己的类表示 。Mixins 是一种用于代码重用的通用 OOP 模式,下面是一个简化的例子:
function ShoppingCart() {this.items = [];}var orderMixin = {calculateTotal() {// 从 this.items 计算}// .. 其他方法}Object.assign(ShoppingCart.prototype, orderMixin)var cart = new ShoppingCart()cart.calculateTotal()
JavaScript 不支持多重继承,因此 mixin 是重用共享行为和扩充类的一种方式 。那该如何在使用 createClass 创建的组件之间共享逻辑呢?Mixins 是一种常用的模式,它可以访问组件的生命周期方法,允许我们组合逻辑、状态等:var SubscriptionMixin = {getInitialState: function() {return {comments: DataSource.getComments()};},// 当一个组件使用多个 mixin 时,React 会尝试合并多个mixin的生命周期方法,因此每个都会被调用componentDidMount: function() {console.log('do something on mount')},componentWillUnmount: function() {console.log('do something on unmount')},}// 将对象传递给 createClassvar CommentList = React.createClass({// 在 mixins 属性下定义它们mixins: [SubscriptionMixin, AnotherMixin, SomeOtherMixin],render: function() {var { comments, ...otherStuff } = this.statereturn (<div>{comments.map(function(comment) {return <Comment key={comment.id} comment={comment} />})}</div>)}})
对于较小的应用,这种方式可以正常运行 。但是,当 Mixin 应用到大型项目时,它们也有一些缺点:- 名称冲突:Mixin 具有共享的命名空间,当多个 Mixin 使用同一个方法或状态的名称时,会发生冲突 。
- 隐式依赖关系:确定哪个 Mixin 提供了哪些功能或状态比较麻烦 。它们使用共享的属性键相互交互,从而创建隐式耦合 。
- 难以理解和调试:Mixin 通常使组件更难以理解和调试 。例如,上面多个 Mixin 都可以对 getInitialState 结果有影响,使得跟踪问题变得更加困难 。
高阶组件当 Javascript 中支持了原生类语法后,React 团队就在 v15.5 中弃用了 createClass API,支持原生类 。
在这个转变过程中,我们仍然按照类和生命周期的思路来思考,因此没有进行重大的心智模型转变 。现在可以扩展包含生命周期方法的 Reacts Component 类:
class MyComponent extends React.Component {constructor(props) {// 在组件挂载到 DOM 之前运行// super 指的是父 Component 的构造函数super(props)}componentWillMount() {}componentDidMount(){}componentWillUnmount() {}componentWillUpdate() {}shouldComponentUpdate() {}componentWillReceiveProps() {}getSnapshotBeforeUpdate() {}componentDidUpdate() {}render() {}}
【React API 和代码重用的演变!】考虑到 mixin 的缺陷,我们该如何以这种编写 React 组件的新方式来共享逻辑和副作用呢?这时候,高阶组件 (HOC) 就出现了,它的名字来源于高阶函数的函数式编程概念 。它成为了替代 Mixin 的一种流行方式,并出现在像 Redux 这样的库的 API 中,例如它的 connect 函数,用于将组件连接到 Redux 存储 。除此之外,还有 React Router 的 withRouter 。
// 一个创建增强组件的函数,有一些额外的状态、行为或 propsconst EnhancedComponent = myHoc(MyComponent);// HOC 的简化示例function myHoc(Component) {return class extends React.Component {componentDidMount() {console.log('do stuff')}render() {// 使用一些注入的 props 渲染原始组件return <Component {...this.props} extraProps={42} />}}}
高阶组件对于在多个组件之间共享通用行为非常有用 。它们使包装的组件保持解耦和通用性,以便可以重用 。然而,HOC 遇到了与 mixin 类似的问题:- 名称冲突:因为 HOC 需要转发和传播 ...this.props 到包装的组件中,所以嵌套的 HOC 相互覆盖可能会发生冲突 。
推荐阅读
- 和田玉籽料|历代的“装饰玉器”:(1)玉簪
- 杨洋|杨洋,买超,曾黎,吴签,任敏
- 小曾|在朋友圈吐槽领导和同事,惨痛的四点教训
- 地下城与勇士|DNF:本以为三觉是惊喜,没想到是惊吓和失望
- 鲍鱼的做法及清洗 鲍鱼怎么做和清洗
- 核桃泡酒的功效和作用 核桃泡酒有什么好处
- 江珊|当年杨志刚和江珊拍戏,江珊说:弟弟啊,姐的屁股翘吗?
- 和田玉籽料|明 和田玉籽料 黄玉 瑞兽 把件 摆件 纸镇
- 周慧敏|51岁的周慧敏晒出自己的照片,穿着复古工装裤,和丈夫甜蜜约会
- 饵料|初夏野钓三款自制饵料和窝料推荐,比买的要强!