前面我们讲到了 HOC 的一些探索, 今天开看看在实际工作中我们如果利用 HOC
1. 切换是否启用新功能
考虑当我们的 APP 已经在线上了, 但是我们正在积极的增加一些新的特性。 当我们修改代码时我们使用 pull request。 一旦一个 PR(pull request) 经被审查, 它将被合并并触发 build 过程, 包括运行测试用例, 并且如果测试跑通过, 它将直接部署到线上环境。我们的每一个新特性通常被分解成较小的工作组, 团队可以发布和合并一个或者多个 PR。所以直到我们准备发布时, 用户都不能体验到新的特性。那如果来先给一部分用户使用的新特性来测试呢
我们需要一个简单的 显示/隐藏
组件来达到这个效果。我们可以使用 HOC 来帮助我们。
featureToggle.js
然后, HOC 可以这样写
这个 HOC 只是简单的根据我们的逻辑来显示或者隐藏特性。所以我们可以默认隐藏它,而给特定的用户打开这个功能。
当我们确定发布时,我们只需要修改这一行代码。
这样,新特性就能以最少的代码修改来发布了。
2. 通过一些三方工具追踪页面加载
(3.13 更新)
有时候我们需要通过一些工具来追踪每个页面访问的数据, 但是我们的App中有很多不同的页面。
- 过滤页面
- 搜索结果页面
- 详情页面
不同的页面,我们想追踪的数据是不同。例如,在搜索页面我们想追踪现在页面的数字,搜索结果的总条数和用户搜索的地点,来了解这个地方最流行的搜索词是什么。现在我们来用 HOC 解决这个问题。
最粗鲁的方法
实际上我们需要在 componentDidMount 和 componentDidUpdate 中调用我们的追踪模块方法, 然后给不同的页面传递特定的信息。
|
|
在 componentDidUpdate 中调用 tracker 是必须的, 因为当用户从一个页面结果导航到下一个或者前一个页面时, SearchResults 组件不会重新创建, 它只会被刷新并且从新渲染新的数据。
搜索过滤页面和详情页面也是差不多这样来实现。
这种特定的实现方法有两个主要的问题:
- 重复代码 - 所有不同的页面处理组件都需要在同样的地方写相同的代码。trackingData()的实现可以给每个页面,但是调用 tracking 不行。
- 违背了单一性原则 - 页面处理组件既要渲染页面布局, 又要追踪数据加载。
用 Mixins 来解决
第一个解决了上面带来的问题的是使用 React mixins。 通过引入一个模块来为 React 组件实现一个特定的功能。例如,我们用 mixins 来做页面的追踪
注意这个 mixin 需要组件实现了 trackingData 方法来返回任何需要追踪的数据。
现在 SearchResults 组件可以用这个来重构
注意 mixins 的声明位置。
同样的 mixins 可以用在其他所有的组件上。 这样,每一个页面组件只需要实现适当的 trackingData 方法,然后 mix-in 这个 pageLoadTrackingMixin 就行了。
但是,这样同样有一些问题。详细可以在这篇博客看看。
主要的内容是:
组件和 minxins 之间的协议是隐藏的。mixins 通常需要依赖组件确定定义的方法,但是 mixins 没办法看到组件定义了什么。
用 HOC 来解决
在上面博客的末尾,作者推荐了使用高阶组件来替代 mixins,像这样:
注意 HOC 代理了我们要追踪的组件的 componentDidMount 和 componentDidUpdate 方法,这和 mixins 很相似,但是它明确的表示需要 trackingData 函数来传递要追踪的数据。这意味着,当一个被这个 HOC 封装的组件渲染时,我们需要传递给它一个 trackingData prop:
现在 SearchResults 组件中所有的追踪逻辑都可以移除,只剩下渲染逻辑了:
对比使用 mixins 的例子,pageLoadTracking 和它的使用者之间的协议变得更明确了,并且计算追踪数据和页面加载追踪的逻辑和渲染逻辑分开了,符合单一性原则。
桌面/手机 APP切换
(待续)