useCallBack,useMemo,forwardRef,useImperativeHandle用法总结

2021.6.19更:
useImperativeHandle的第一个参数为ref句柄,即父组件传递到子组件的ref属性,


image.png

useImperativeHandle和子组件第二位预留参数ref的使用需要forwardRef高阶组件的配合:


image.png

但有时候我们不想使用forwardRef高阶组件,即子组件预留的第二位参数ref失效
这时候需要手动往子组件props参数中传递xxxref,通过xxxref和useImperativeHandle一样能达到获取子组件属性和api的作用,且不需要使用forwardRef高阶组价了

image.png

image.png

useCallBack & useMemo

用法:

useMemo 和 useCallback 接收的参数都是一样,第一个参数为回调 第二个参数为要依赖的数据

const ds = useMemo(() => new DataSet({xxx}), []); // 缓存了new出来的DataSet实例
const fn = useCallBack(() => {}, []); // 仅仅是缓存这个函数 不让fn随便刷新

共同点

1.仅仅 依赖数据 发生变化, 才会重新计算结果,也就是起到缓存的作用。

区别点

1.useMemo 计算结果是 return 回来的值, 主要用于 缓存计算结果的值 ,应用场景如: 需要 计算的状态

2.useCallback 计算结果是 函数, 主要用于 缓存函数,应用场景如: 需要缓存的函数,因为函数式组件每次任何一个 state 的变化 整个组件 都会被重新刷新,一些函数是没有必要被重新刷新的,此时就应该缓存起来,提高性能,和减少资源浪费。

forwardRef

用法:

1.父组件传递子组件ref,子组件拿到ref并放到对应的dom上,例如Input,父组件就能调用子组件input的相关api(涉及dom)

useImperativeHandle

用法:

父组件传递给子组件的ref,通过useImperativeHandle可以拿到子组件所有的变量和api

useImperativeHandle(ref, ()=>({
    [api],
    [变量],
}))

拓展思考

虽然forwardRef和useImperativeHandle配合使用完全能达到想要的父调子所有api和dom的效果,但是使用forwardRef需要把函数组件当参数才能起到转发父组件props和ref的作用,但是往往一个组件需多个高阶组件嵌套,例如observer(),connect()等混合使用时, 它们如何一起使用呢?

const Index = forwardRef(() => {});
const Index = observer(() => {});
const Index = connect(() => {});

lodash 提供了 'compose' api供合并执行函数:

compose(connect(arg), observer(agr2), ...)(Index)合并执行的方法

observer, connect等是高阶组件,高阶组件通过 1. 属性继承 2. 反向代理3.渲染劫持...从而达到api实现的效果,例如:

把global参数传递进去

connect(global = {})(Index) // 先执行const fn = connect(gloabl)

高阶函数接受参数组件作为参数返回一个新的组件

const NewCom = fn(Index)

最后我们再export default NewCom

合并在一起就是

export default compose(connect(global = {}), observer(global = {}), forwardRef())(Index);

你可能感兴趣的:(useCallBack,useMemo,forwardRef,useImperativeHandle用法总结)