总述
有时候我们会想要在组件之间重用一些状态逻辑。
目前为止,有两种主流方案来解决这个问题:高阶组件 和 render props。
当我们想在两个函数之间共享逻辑时,我们会把它提取到第三个函数中。而组件和 Hook 都是函数,所以也同样适用这种方式。
自定义 Hook 可以让你在不增加组件的情况下达到同样的目的。
什么是自定义 Hook?
将一些常用的、跨越多个组件的Hook功能,抽离出去形成一个函数,该函数就是自定义Hook。
自定义 Hook 是一个函数,其名称以 “use
” 开头,函数内部可以调用其他的 Hook。
每个组件间的 state 是完全独立的。Hook 是一种复用 状态逻辑 的方式,它不复用 state 本身。事实上 Hook 的每次调用 都有一个完全独立的 state —— 因此你可以在单个组件中多次调用同一个自定义 Hook。
自定义 Hooks 函数偏向于功能,而组件偏向于界面和业务逻辑。由于差别不大,所以使用起来也
是很随意的。
自定义Hook的使用
自定义Hook,由于其内部需要使用Hook功能,所以它本身也需要按照Hook的规则实现:
- 函数名必须以use开头
- 调用自定义Hook函数时,应该放到顶层
当然,使用高阶组件,也可实现相同的封装。但是,你会发现:
- 没有Hook方式来得优雅
- 高阶组件会导致组件层次嵌套变深
什么是高阶组件?
一个高阶组件只是一个包装了另外一个 React 组件的 React 组件。
这种形式通常实现为一个函数,本质上是一个类工厂(class factory),它下方的函数标签伪代码启发自 Haskell
hocFactory:: W: React.Component => E: React.Component
这里 W(WrappedComponent) 指被包装的 React.Component,E(Enhanced Component) 指返回的新的高阶 React 组件。
定义中的『包装』一词故意被定义的比较模糊,因为它可以指两件事情:
- 属性代理(Props Proxy):高阶组件操控传递给 WrappedComponent(被包装的组件) 的 props,
- 反向继承(Inheritance Inversion):高阶组件继承(extends)WrappedComponent(被包装的组件)。
我可以使用高阶组件做什么呢?
概括的讲,高阶组件允许你做:
- 代码复用,逻辑抽象,抽离底层准备(bootstrap)代码
- 渲染劫持
- State 抽象和更改
- Props 更改
在探讨这些东西的细节之前,我们先学习如何实现一个高阶组件,因为实现方式『允许/限制』你可以通过高阶组件做哪些事情。接下来我们再一点点在项目中进行实践。
参考资料:
深入理解 React 高阶组件 - 简书
Render Props – React