设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

【React深入】从Mixin到HOC再到Hook(11)

发布时间:2019-04-11 17:31 所属栏目:21 来源:ConardLi
导读:如果我们在高阶组件对原组件进行了修改,例如下面的代码: InputComponent.prototype.componentWillReceiveProps=function(nextProps){...} 这样就破坏了我们对高阶组件的约定,同时也改变了使用高阶组件的初衷:我

如果我们在高阶组件对原组件进行了修改,例如下面的代码:

  1. InputComponent.prototype.componentWillReceiveProps = function(nextProps) { ... } 

这样就破坏了我们对高阶组件的约定,同时也改变了使用高阶组件的初衷:我们使用高阶组件是为了增强而非改变原组件。

约定-透传不相关的props

使用高阶组件,我们可以代理所有的props,但往往特定的HOC只会用到其中的一个或几个props。我们需要把其他不相关的props透传给原组件,如下面的代码:

  1. function visible(WrappedComponent) {  
  2.   return class extends Component {  
  3.     render() {  
  4.       const { visible, ...props } = this.props;  
  5.       if (visible === false) return null;  
  6.       return <WrappedComponent {...props} />;  
  7.     }  
  8.   }  

我们只使用visible属性来控制组件的显示可隐藏,把其他props透传下去。

约定-displayName

在使用React Developer Tools进行调试时,如果我们使用了HOC,调试界面可能变得非常难以阅读,如下面的代码:

  1. @visible  
  2. class Show extends Component {  
  3.   render() {  
  4.     return <h1>我是一个标签</h1>  
  5.   }  
  6. }  
  7. @visible  
  8. class Title extends Component {  
  9.   render() {  
  10.     return <h1>我是一个标题</h1>  
  11.   }  

为了方便调试,我们可以手动为HOC指定一个displayName,官方推荐使用HOCName(WrappedComponentName):

  1. static displayName = `Visible(${WrappedComponent.displayName})` 

这个约定帮助确保高阶组件最大程度的灵活性和可重用性。

使用HOC的动机

回顾下上文提到的 Mixin 带来的风险:

  •  Mixin 可能会相互依赖,相互耦合,不利于代码维护
  •  不同的 Mixin 中的方法可能会相互冲突
  •  Mixin非常多时,组件是可以感知到的,甚至还要为其做相关处理,这样会给代码造成滚雪球式的复杂性

而HOC的出现可以解决这些问题:

  •  高阶组件就是一个没有副作用的纯函数,各个高阶组件不会互相依赖耦合
  •  高阶组件也有可能造成冲突,但我们可以在遵守约定的情况下避免这些行为
  •  高阶组件并不关心数据使用的方式和原因,而被包裹的组件也不关心数据来自何处。高阶组件的增加不会为原组件增加负担

HOC的缺陷

  •  HOC需要在原组件上进行包裹或者嵌套,如果大量使用HOC,将会产生非常多的嵌套,这让调试变得非常困难。
  •  HOC可以劫持props,在不遵守约定的情况下也可能造成冲突。

Hooks

Hooks是React v16.7.0-alpha中加入的新特性。它可以让你在class以外使用state和其他React特性。

使用Hooks,你可以在将含有state的逻辑从组件中抽象出来,这将可以让这些逻辑容易被测试。同时,Hooks可以帮助你在不重写组件结构的情况下复用这些逻辑。所以,它也可以作为一种实现状态逻辑复用的方案。

阅读下面的章节使用Hook的动机你可以发现,它可以同时解决Mixin和HOC带来的问题。

官方提供的Hooks

State Hook

我们要使用class组件实现一个计数器功能,我们可能会这样写:

  1. export default class Count extends Component {  
  2.   constructor(props) {  
  3.     super(props);  
  4.     this.state = { count: 0 }  
  5.   }  
  6.   render() {  
  7.     return (  
  8.       <div>  
  9.         <p>You clicked {this.state.count} times</p>  
  10.         <button onClick={() => { this.setState({ count: this.state.count + 1 }) }}>  
  11.           Click me  
  12.         </button>  
  13.       </div>  
  14.     )  
  15.   }  

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读