ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现

高阶组件

  • 高阶组件就是一个函数,传给她一个组件,它返回一个新的组件。
  • 高阶组件的作用其实就是为了组件之前的代码复用。

高阶组件的用处,属性代理, 方向继承

属性代理

像之前实现的redux的connext就是使用高阶组件的写法。
在这里插入图片描述
通过高阶组件传入了一个title属性,如果所有组件都需要这个属性,只需要使用这个高阶函数代理一下即可。
在这里插入图片描述
使用装饰器的写法会报错,因为它不支持。所以我们安装一个plugin.
在这里插入图片描述
然后在babel.config.js文件进行配置在这里插入图片描述
在书写一个jsconfig.json文件
在这里插入图片描述
这样就可以i使用装饰器了,装饰器的功能是会将类传入装饰其中,然后去加强类的一些比如属性和方法。如果装饰器中返回一个值,那么会将该值作为最终的值。也就是我们渲染出来的vdom。
具体可以了解这篇装饰器

高阶函数第二个特点,反向继承

拦截生命周期,拦截state,渲染过程。
在这里插入图片描述
我们继续使用这个。然后使用高阶组件,反向继承,在这里插入图片描述
方法就是让返回的类继承传入的类,接着就可以通过super进行一系列的操作,拦截生命周期,渲染状态等等在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们没调用Home的componnetWillMount,他就不会执行。
cloneElement方法的实现:
在这里插入图片描述
主要就是浅复制返回一个对象。

多个context的实现

react对context的实现是
 duo
而我们对context的实现是这样的,在这里插入图片描述
所以我们重新改造一下。
在这里插入图片描述
让createContext返回一个对象,标识typeof,因为babel转化的时候会根据这个转化,最后在创建的时候针对处理这个vdom就行。
在这里插入图片描述
在这里插入图片描述
因为我们现在的vdom不止三种类型了,有原生dom,函数组件,类组件,provider组件,forwardref组件,consumer组件。
在这里插入图片描述
在compareTwoVdom的里面调用的updateElement方法也应该做出改变,因为现在的div下面可能有的是Provier组件,有的是Consumer组件,所以必须做出对应的判断在这里插入图片描述
不管是什么类型的vdom,更改的时候都是要拿到对应的vdom去进行比对。而provider组建的vdom上的props的children就是指向里层的vdom。
这样就完成了对context的改造。
针对provier和consumer组件做标识,在创建的时候处理,将value赋值到返回的context对象中,然后在render之前再将Value传给context属性。

render props

  • render props是一种在React组件之间使用的一个值为函数的prop共享代码的简单技术。
  • 具有render prop的组件接受一个函数,该函数返回一个React元素并调用它,而不是实现自己的渲染逻辑。
  • render prop是一个用于告知组件需要渲染什么内容的props
  • 这也是逻辑复用的一种方式。

例子

在这里插入图片描述
在这里插入图片描述
这时候渲染的内容是不是固定的?我们无法改变,所以需要从外界传入进来。首先是

children

在这里插入图片描述
通过children传入

props

在这里插入图片描述
通过props传入。

  • render-prop可以与HOC(高阶组件)互换
    在这里插入图片描述
    Home只注重渲染,Wrapper注重逻辑这就是转换成HOC的写法。
    render-prop就是接受一个值为函数的props的属性,如porp.render,这个render返回一个react元素,用来作为渲染的内容,render-prop组件本身没有渲染内容,增加复用性。

Purcomponent的实现

继承Purcomponent的组件会默认调用shouldComponent方法对新老的Props和state进行比较,返回true即更新,返回false即不更新。
我们先看现在的实现
在这里插入图片描述
即使state中的number是一样的,但是还是会重新render
在这里插入图片描述
这样是不对的,所以我们要实现PureComponent的效果。
思路就是Purcomponent继承了Component并且重写了ShouldComponentUpdate方法。 在这里插入图片描述
实现方法很简单,重写shouldComponentUpdate方法即可,通过shallowEqual比对新老state,和新老Props。
在这里插入图片描述
主要是对传入的两个对象进行浅比较。
看效果:
在这里插入图片描述
在这里插入图片描述
输入0的时候,1+0还是1,所以state不
变。所以不会渲染。当
在这里插入图片描述
再将father组件换位Component试试
在这里插入图片描述
在这里插入图片描述
即使state不变,但是father组件依然会重新render。所以PurComponent组件就实现完毕了。

函数组件的实现方式 React.memo

源码的memo实现
在这里插入图片描述
也是标识类型$$typeof,由babel转化为这个对象。
在这里插入图片描述
第二个参数是一个比对函数,默认实现的是

(preProps, nextProps)=>shallowEqual(preProps, nextProps)

react内部有实现shallowEqual这个方法。
我们来实现memo这个方法。
首先看在这里插入图片描述
再看memo方法的实现
在这里插入图片描述
这里需要注意一下,与Provier,Consumer,ForwardRef一样,memo返回的也是一个对象,当他作为一个元素渲染的时候,会被babel转化为类似这样
在这里插入图片描述
也就是说memo的组件会被转化为

React.createElement({$$typeof: REACT_MeMo,comapre,  type, } ,{id: 123123})

即最终的rencet元素应该是这样的在这里插入图片描述
Provider跟ConSumer也是同样的道理。
memo的实现并不难,难的是处理这个元素。
在这里插入图片描述
在这里插入图片描述
这里需要将老的props放到vdom上方便比较,这就是首次渲染的memo组件应该处理的事情。如图:
在这里插入图片描述

在这里插入图片描述
修改的时候,也要根据type值的不同做处理、
在这里插入图片描述
在这里插入图片描述
这样就完成了对Memo的处理,看效果:
在这里插入图片描述
在这里插入图片描述
memo组件就完成了。

猜你喜欢

转载自blog.csdn.net/lin_fightin/article/details/120939990