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

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

发布时间:2019-04-11 17:31 所属栏目:21 来源:ConardLi
导读:通过反向继承实现 functionhijackHOC(WrappedComponent){ returnclassextendsWrappedComponent{ render(){ consttree=super.render(); letnewProps={}; if(treetree.type==='input'){ newProps={value:'渲染被劫持

通过反向继承实现

  1. function hijackHOC(WrappedComponent) {  
  2.   return class extends WrappedComponent {  
  3.     render() {  
  4.       const tree = super.render();  
  5.       let newProps = {};  
  6.       if (tree && tree.type === 'input') {  
  7.         newProps = { value: '渲染被劫持了' };  
  8.       }  
  9.       const props = Object.assign({}, tree.props, newProps);  
  10.       const newTree = React.cloneElement(tree, props, tree.props.children);  
  11.       return newTree;  
  12.     }  
  13.   }  

注意上面的说明我用的是增强而不是更改。render函数内实际上是调用React.creatElement产生的React元素:

虽然我们能拿到它,但是我们不能直接修改它里面的属性,我们通过getOwnPropertyDescriptors函数来打印下它的配置项:

可以发现,所有的writable属性均被配置为了false,即所有属性是不可变的。(对这些配置项有疑问,请👇defineProperty)

不能直接修改,我们可以借助cloneElement方法来在原组件的基础上增强一个新组件:

React.cloneElement()克隆并返回一个新的React元素,使用 element 作为起点。生成的元素将会拥有原始元素props与新props的浅合并。新的子级会替换现有的子级。来自原始元素的 key 和 ref 将会保留。

React.cloneElement() 几乎相当于:

  1. <element.type {...element.props} {...props}>{children}</element.type> 

如何使用HOC

上面的示例代码都写的是如何声明一个HOC,HOC实际上是一个函数,所以我们将要增强的组件作为参数调用HOC函数,得到增强后的组件。

  1. class myComponent extends Component {  
  2.   render() {  
  3.     return (<span>原组件</span>)  
  4.   }  
  5. }  
  6. export default inheritHOC(myComponent); 

compose

在实际应用中,一个组件可能被多个HOC增强,我们使用的是被所有的HOC增强后的组件,借用一张装饰模式的图来说明,可能更容易理解:

假设现在我们有logger,visible,style等多个HOC,现在要同时增强一个Input组件:

  1. logger(visible(style(Input))) 

这种代码非常的难以阅读,我们可以手动封装一个简单的函数组合工具,将写法改写如下:

  1. const compose = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));  
  2. compose(logger,visible,style)(Input); 

compose函数返回一个所有函数组合后的函数,compose(f, g, h) 和 (...args) => f(g(h(...args)))是一样的。

很多第三方库都提供了类似compose的函数,例如lodash.flowRight,Redux提供的combineReducers函数等。

Decorators

我们还可以借助ES7为我们提供的Decorators来让我们的写法变的更加优雅:

  1. @logger  
  2. @visible  
  3. @style  
  4. class Input extends Component {  
  5.   // ...  

(编辑:ASP站长网)

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