前言: 已经有了Class Component,为什么又来了一个hooks ?
我们知道组件和自上而下的数据流可以帮助我们将大型UI组织成小型,独立,可以重用的部分.但是由组件的是由逻辑与UI组成,我们是没办法进一步破坏组件的封装特性的.同时逻辑是有状态的,因此无法提取到函数或者其他组件中.hook 让我们可以将组件内部的逻辑组织成可以重用的单元.基于这一点,Hook 实现了状态逻辑与UI 的解耦,将状态的计算和改变交给hook处理,因此React组件不会随着业务的增长而变得臃肿.Hooks最大的优势其实还是对于状态逻辑的复用便捷,代码的简洁。
Hook 之前的逻辑复用:
1.直接复写逻辑:CM+C ,CM+V
2.高阶组件:
1.高阶组件的props都是直接透传下来,无法确实子组件的props的来源。
2.可能会出现props重复导致报错。
3.组件的嵌套层级太深。
4.会导致ref丢失
Hook 实现原理:
hook 节点源码: Hook 的调用后会生成一个顺序表,hook 变化之后 hook 队列会直接存取的方式去修改 hook 节点内容,这也就是为什么不能打乱 hook 的调用顺序。
下面这是一个网友用数组简单模拟hook 实现,大概的思路其实就是这样的,只是没有这么暴力,react 本身做了很多优化,封装,这张图可以方便大家的理解。
下面是 hook 的一些源码:看完就清楚这些 hook 本质就是一个个函数
常用的 Hook: useState ,useEffect
useState:
const [visible, setVisible] = useState(false);
useEffect:
React更新 Dom后执行的某些操作,比如网络请求等,在默认情况下,useEffect 在第一次渲染和每次更新之后都会执行,并且 React 会保证每次运行的 effect 的时候,DOM 都已经更新完毕了。所有所以我们也就没必要去考虑组件是挂载还是更新了。但是每次渲染都会执行 effect 肯定会导致性能问题,所有就有了 useEffect hook 的第二个参数 ,可以通过传入一个state 变量的数组进行管理(如下下图),effect 只会在数组内的变量的值改变时进行调用。(如果传入一个空数组,那么这个 effect hook 则只会在组件挂载和卸载时候进行调用)
Hook 的使用规则:
1.只在最顶层使用hook ,不要在循环,条件,等可以打破执行顺序的语句中执行hooks,以确保每次渲染,hook 的调用顺序是相同的。
2.只在函数组件,自定义 Hook 中调用 Hook,不要在普通的业务函数中调用 Hook
3 .如果要条件的调用 Hooks,那么需要把条件放在 useEffect 里面
自定义的 Hooks :
自定义 hook 是以‘use’开头的一个函数。我们提取自定义 hook 是为了把多个函数中共同的逻辑抽离成一个状态逻辑复用的函数,与在多个函数中重复写逻辑没有本质的区别。因此在调用的时候是相互隔离的,并不会共享 state ,就如同我们多次调用useState 一样,他们是相互隔离的。
注意点:在自定义的 hook 中调用其他的 hook 确保要在顶层无条件的调用。
useModalVisible 返回 visible,setVisible ,colseModal ,openModal, 这是对隐藏显示逻辑的封装,所有的 Modal ,Drawer 都可以使用。下面是 Hook 内部的实现:
自定义Modal hook
网友评论