高阶组件(Higher-Order Components)
高阶组件(HOC)是 React 中用于重用组件逻辑的高级技术。 HOC 本身不是 React API 的一部分。 它们是从 React 构思本质中浮现出来的一种模式。
具体来说,高阶组件是一个函数,能够接受一个组件并返回一个新的组件。
实现高阶组件的方法
- 属性代理 高阶组件通过包裹 react 组件来操作 props
- 反向继承 高阶组件继承于被包裹的 react 组件
属性代理
我们通过一个例子来说明:
1 |
|
其中最重要的部分是 render 方法中返回了传入的 react 组件TargetComponent
,同时往TargetComponent
中传入了我们自己的newProps
属性,这种方法即为属性代理。
使用这个高阶组件非常容易:
1 |
|
有时候,我们调用高阶组件的时候需要传入一些参数,这个实现非常简单,我们修改一下上面的方法:
1 |
|
通过 refs 获取组件实例
下方例子中,我们实现了通过 ref 获取 TargetComponnet 实例并调用实例方法。
1 |
|
1 |
|
控制台返回:
反向继承
-
react 高阶组件有一种叫反向继承(Inheritance Inversion),简称 II。
反向继承可以这样简单实现:
1 |
|
如你所见,返回的高阶组件类HOCII
继承了 TargetComponnet
。这被叫做反向继承是因为 TargetComponnet
被动地被 HOCII
继承,而不是 TargetComponnet
去继承 HOCII
。通过这种方式他们之间的关系倒转了。
反向继承允许高阶组件通过 this 关键词获取 TargetComponnet
,意味着它可以获取到 state,props,组件生命周期(component lifecycle)钩子,以及渲染方法(render)。
我们在HOCII
上打印一下this
看看
1 |
|
我们可以看到在
HOCII
中成功获取到了HOCDemo
的各种属性方法
可以用反向继承高阶组件做什么?
- 渲染劫持(Render Highjacking)
- 操作 state
渲染劫持
通过渲染劫持你可以:
- 根据条件不同,选择性的渲染子树(此功能属性代理也能实现,这里不做赘述)
- 在渲染方法中读取或更改 React Elements tree,也就是 WrappedComponent 的 children
- 给子树里的元素变更样式
- 『读取、添加、修改、删除』任何一个将被渲染的 React Element 的 props
改造一下 HOCII:
1 |
|
1 |
|
结果:
我们可以看到,HOCDemo 中的 input 的 value 和 style 已经被我们改掉了
操作 state
高阶组件可以 『读取、修改、删除』TargetComponnet
实例的 state,如果需要也可以添加新的 state。需要记住的是,你在弄乱 TargetComponnet
的 state,可能会导致破坏一些东西。通常不建议使用高阶组件来读取或添加 state,添加 state 需要使用命名空间来防止与 TargetComponnet
的 state 冲突。