门户网站建设和推广,成都网站建设哪家专业而且比较便宜,网站一般多少钱一年,福州网络营销推广公司作者 | #x1f47d;来源 | 前端Sharing前言自从vue3.0正式发布之后#xff0c;vue3.0核心响应式部分被单独抽离成vue/reactivity包#xff0c;也就是说#xff0c;我们可以脱离vue框架之外#xff0c;单独使用vue/reactivity做一些其他的愉快的事#x1f60a;#xff0… 作者 | 来源 | 前端Sharing前言自从vue3.0正式发布之后vue3.0核心响应式部分被单独抽离成vue/reactivity包也就是说我们可以脱离vue框架之外单独使用vue/reactivity做一些其他的愉快的事于是乎笔者突发奇想为何不用vue/reactivity在react中构建响应式省着每次调用this.setState,useState直接通过改变state值做到更新视图。说干就干为了可以量化生产复用逻辑我在function组件中写了一个自定义hooks-useReactive 在class组件中写了一个高阶组件reactiveHoc。在 react 写 vue 是不是有点不讲武德呢?实际写这篇文章的目的是1 在重温一下vue3.0响应式原理reactive 和 effect。2 如何编写一个响应式的自定义hooks学会写自定义hook。3 如何编写一个响应式的HOC,学会写hoc。函数组件-自定义hooks编写useReactive自定义hooksimport { reactive, effect } from vue/reactivity
import React, { useRef , useEffect, useMemo, useState } from react
function useReactive (initState){const reactiveState useRef(initState) // 用const [ ,forceUpdate ] useState(0)const state useMemo(() reactive(reactiveState.current) ,[ reactiveState.current ]) useEffect((){let isdep falseeffect((){for(let i in state ){ state[i] } //依赖收集isdep forceUpdate(num num 1) // 强制更新if(!isdep) isdep true})},[ state ])return state
}思路① 用useRef保存响应式对象并构建响应式为什么选择useRef,在函数组件执行更新中,只有Ref-Hooks一直使用的是原始对象这之前的hooks原理中讲过。这样做的好处防止函数组件更新时候响应式对象丢失。② 用useMemo缓存响应式对象当Ref对象被篡改重新构建响应式。③ 用useEffect做响应式的依赖收集用开关isdep防止初始化vue/reactivity的 effect初始化执行时引起的forceUpdate引发的额外的组件更新。④ 用一个useState做强制更新。⑤ 在effect对象中for(let i in state ){ state[i] }遍历 Ref对象 做依赖收集。使用function Index(){const state useReactive({ number:1 , name:alien })return div classNamebox div classNameshow div 你的姓名是: { state.name } /divdiv{ new Array(state.number).fill(0).map(() ) }/div/divdiv classNameconstrol div button onClick{ () state.number } /button /divdiv button onClick{ () state.number-- } --/button /divinput placeholder姓名 value{state.name} onChange{ (e:any) state.name e.target.value } / /div/div
}效果类组件-反向继承hoc在function组件中我们可以使用自定义hook构建响应式; 那么在class类组件中我们如何构建响应式呢每次在业务组件中引进reactive和effect手动绑定显然不是很切合实际也不是我们的追求这个时候hoc高阶组件就派上用场了。我们接着往下看编写reactiveHoc高阶组件import { reactive , effect } from vue/reactivity
import React from react
function reactiveHoc(Component){const self_componentDidMount Component.prototype.componentDidMountreturn class WrapComponent extends Component{constructor(props){super(props)this.state reactive(this.state)}__isFirst falsecomponentDidMount(){effect((){for(let i in this.state ){ this.state[i] } //构建响应式this.__isFirst this.forceUpdate()!this.__isFirst (this.__isFirst true ) }) self_componentDidMount self_componentDidMount.call(this)}}
}思路为什么要选择反向继承模式 HOC 呢 因为我们可以通过一个反正继承的hoc访问到内部的state状态,对于内部的state进行reactive响应式处理。劫持类组件周期componentDidMount在hoc的componentDidMount中同样做依赖收集。使用reactiveHoc
class Index extends React.Component{constructor(props){super(props)this.state{number:0,name:alien}}componentDidMount(){console.log(6666)}render(){const { state } :any thisreturn div classNamebox div classNameshow div 你的姓名是: { state.name } /divdiv{ new Array(state.number).fill(0).map(() ) }/div/divdiv classNameconstrol div button onClick{ () state.number } /button /divdiv button onClick{ () state.number-- } --/button /divinput placeholder姓名 value{state.name} onChange{ (e:any) state.name e.target.value } / /div/div}
}总结本文主要的目的并不是教大家在react用vue/reactivity构建响应式可以当娱乐玩玩罢了主要目的是结合上两篇文章教大家更好编写自定义hooks和 hoc。早日进阶react技术栈。往期推荐如果让你来设计网络70% 开发者对云原生一知半解“云深”如何知处浅述 Docker 的容器编排如何在 Kubernetes Pod 内进行网络抓包点分享点收藏点点赞点在看