usePersistFn可以持久化function,保证函数地址永远不会变化。

成都创新互联公司坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站建设、做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的逊克网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!
import { useRef } from 'react';
export type noop = (...args: any[]) => any;
function usePersistFn(fn: T) {
  const fnRef = useRef(fn);
  // 每次渲染fn的最新值都会记录在fnRef中
  fnRef.current = fn;
  const persistFn = useRef();
  // 初次渲染时给persistFn赋值,此后persistFn不会更新
  if (!persistFn.current) {
    persistFn.current = function (...args) {
      return fnRef.current!.apply(this, args);
    } as T;
  }
  // 返回persistFn,感叹号表示返回值类型非null或undefined,因为初次渲染时persistFn就被赋值为了函数
  return persistFn.current!;
}
export default usePersistFn;   
在React官方文档中提到
在某些场景中,你可能会需要用 useCallback 记住一个回调,但由于内部函数必须经常重新创建,记忆效果不是很好,导致子组件重复 render。对于超级复杂的子组件,重新渲染会对性能造成影响。通过 usePersistFn,可以保证函数地址永远不会变化。
官方给出的demo如下
function Form() {
  const [text, updateText] = useState('');
  const textRef = useRef();
  useEffect(() => {
    textRef.current = text; // 把它写入 ref
  });
  const handleSubmit = useCallback(() => {
    const currentText = textRef.current; // 从 ref 读取它
    alert(currentText);
  }, [textRef]); // 不要像 [text] 那样重新创建 handleSubmit
  return (
    <>
       updateText(e.target.value)} />
      
    >
  );
}
复制代码
ExpensiveTree是一个复杂的子组件,其接受一个props handleSubmit函数。如果使用useCallback,由于handleSubmit函数内部使用了text变量,便要写为如下形式:
const handleSubmit = useCallback(() => {
    alert(text);
  }, [text]); 
复制代码
只要text发生变化,useCallback接收的内部函数便要重新创建,导致handleSubmit函数的引用地址发生变化。进而引起子组件ExpensiveTree的重渲染,对性能产生影响。
usePersistFn的目标便是持久化接收的函数,且调用时内部函数引用的变量(上例为text)能获取到实时的值(useCallback的依赖传空数组也能实现持久化函数,但无法获取实时的值)
官方给的demo中更新textRef写在了useEffect中,为什么usePersistFn不这样实现?
如果在子组件的useEffect回调函数中调用usePersistFn就会出现问题。因为渲染时会先执行子组件的useEffect,后执行父组件自定义hooks的useEffect。
文章出自:前端餐厅ReTech,如有转载本文请联系前端餐厅ReTech今日头条号。
github:https://github.com/zuopf769
                网站标题:Ahooks源码分析之usePersistFn
                
                转载来于:http://www.csdahua.cn/qtweb/news26/543426.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网