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

高阶组件

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

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

属性代理

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

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

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

多个context的实现

react对context的实现是
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
而我们对context的实现是这样的,ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
所以我们重新改造一下。
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
让createContext返回一个对象,标识typeof,因为babel转化的时候会根据这个转化,最后在创建的时候针对处理这个vdom就行。
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
因为我们现在的vdom不止三种类型了,有原生dom,函数组件,类组件,provider组件,forwardref组件,consumer组件。
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
在compareTwoVdom的里面调用的updateElement方法也应该做出改变,因为现在的div下面可能有的是Provier组件,有的是Consumer组件,所以必须做出对应的判断ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
不管是什么类型的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
  • 这也是逻辑复用的一种方式。

例子

ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
这时候渲染的内容是不是固定的?我们无法改变,所以需要从外界传入进来。首先是

children

ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
通过children传入

props

ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
通过props传入。

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

Purcomponent的实现

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

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

源码的memo实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
也是标识类型$$typeof,由babel转化为这个对象。
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
第二个参数是一个比对函数,默认实现的是

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

react内部有实现shallowEqual这个方法。
我们来实现memo这个方法。
首先看ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
再看memo方法的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
这里需要注意一下,与Provier,Consumer,ForwardRef一样,memo返回的也是一个对象,当他作为一个元素渲染的时候,会被babel转化为类似这样
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
也就是说memo的组件会被转化为

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

即最终的rencet元素应该是这样的ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
Provider跟ConSumer也是同样的道理。
memo的实现并不难,难的是处理这个元素。
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
这里需要将老的props放到vdom上方便比较,这就是首次渲染的memo组件应该处理的事情。如图:
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现

ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
修改的时候,也要根据type值的不同做处理、
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
这样就完成了对Memo的处理,看效果:
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
ZF_react 高阶组件 多个context的实现 render props Purcomponent的实现 React.memo的实现
memo组件就完成了。

上一篇:react生命周期(旧)


下一篇:强化学习 --gym env.render()报错