零、动机
1、在组件之间复用状态逻辑很难,React 需要为共享状态逻辑提供更好的原生途径
2、复杂组件变得难以理解,生命周期内同一个函数内部的操作,可能有获取数据,订阅变动等不相关的逻辑
3、难以理解的 class,JavaScript 中 this 的工作方式
PS:hook在class不起作用,带有hook的函数组件跟class是一样的,可以取代class
一、useState
需要定义成响应式的变量,都需要useState声明,这是函数组件内部的状态变量,
不能在if里面,为函数组件提供了自己的状态变量,
一般来说,在函数退出后变量就会”消失”,而 state 中的变量会被 React 保留
二、useEffect
执行时机:在浏览器完成布局与绘制之后
componentDidMount:会在组件挂载后(插入 DOM 树中)立即调用
componentDidUpdate:会在更新后会被立即调用
销毁:return的函数会在组件即将销毁时(componentWillUnmount)调用,effect 的清除阶段在每次重新渲染(render)之前都会执行,而不是只在即将卸载组件的时候执行一次
useEffect接受两个参数,第一个effect,第二个是依赖,useEffect会在浏览器渲染完成,对比依赖项是否改变,再执行effect
所以uesEffect可以当做componentDidMount, componentDidUpdate, componentWillUnmount的结合
useEffect默认每次重新渲染(render后)都执行
1、阻止每次渲染都执行
useEffect(effect, [value])
以上,在每次组件重新渲染的时候,useEffect会判断value是不是变了,如果没变,就会跳过effect
2、仅在挂载和卸载的时候执行
useEffect(() => { // do something return 'doing'}, [])
3、仅在挂载的时候执行
useEffect(effect)
三、useContext
跨组件层级数据获取
<MyContext.Provider> 的 value 发生变化时候, 调用了 useContext 的组件总会在变化时重新渲染
四、useCallback
返回缓存的函数
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)。
当一个函数被传递给,经过使用引用相等性去避免非必要渲染的子组件时,会很有用,子组件校验函数是否变化
五、useMemo
返回缓存的值(类似于vue 的 computed) ,其他属性同上,传入useMemo的函数会在渲染期间执行,不要在函数内执行与渲染无关的操作
意思就是,dom render的时候,每次都先执行useMemo,之后整合好最新的dom,在交给浏览器渲染
但是主要是用来,在return的dom中使用的变量(包括传入子组件的),每次在state变得时候,在进行渲染,期间,用到的函数和变量,会不分好坏,都执行一遍,所以,为了避免重复工作,用useMemo或者useCallback,来使用缓存,提高性能
六、useRef
useRef 返回一个可变的 ref 对象,其 current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变,类似于组件内的全局变量。useRef 会在每次渲染时返回同一个 ref 对象。变更 .current 属性不会引发组件重新渲染
七、useLayoutEffect
它会在所有的 DOM 变更之后同步调用 effect。可以使用它来读取 DOM 布局并同步触发重渲染,也就是,DOM变更之后 且 渲染之前,会阻塞浏览器绘制。
跟useEffect一样,只是调用时机不一样
八、useImperativeHandle
可以让你在使用 ref 时自定义暴露给父组件的实例值