React函数式组件学习常用的自定义hook

1,408 阅读2分钟

关于hook

以前项目用过react都是类组件的形式,现在函数式组件已经是最流行的了,而hook又是最重要的,除了自带的hook,很多时候都需要在其基础上自定义hook,当然也不是必须使用原有的hook,其实就是一个函数,只是我们在项目过程中需要提取一些公用逻辑时候再根据需要来定制hook

常见的hook

这里总结下目前经常用的hook,遇到就会慢慢更新。

usePrevious

类组件时候componentDidUpdate可以获取prevProps,但是在函数式组件中我们可以利用useRef自定义hook来存储前值。

 function usePrevious(value) {
   const ref = useRef();
   useEffect(() => {
     ref.current = value;
   });
   return ref.current;
 }

useInterval

可以用delay来动态控制定时器,delaynull时候不创建定时器。这里同样利用了useRef来存储新的回调。参考

 function useInterval(callback, delay) {
   const savedCallback = useRef();
 ​
   // 保存新回调
   useEffect(() => {
     savedCallback.current = callback;
   });
 ​
   // 建立 interval
   useEffect(() => {
     function tick() {
       savedCallback.current();
     }
     if (delay !== null) {
       let id = setInterval(tick, delay);
       return () => clearInterval(id);
     }
   }, [delay]);
 }

useResizeObserver

获取某个元素的位置信息,resize时候可以更新。

 const useResizeObserver = ref => {
   const [dimensions, setDimensions] = useState(null);
   useEffect(() => {
     const observeTarget = ref.current;
     const resizeObserver = new ResizeObserver(entries => {
       entries.forEach(entry => {
         setDimensions(entry.contentRect);
       });
     });
     resizeObserver.observe(observeTarget);
     return () => {
       resizeObserver.unobserve(observeTarget);
     };
   }, [ref]);
   return dimensions;
 };

useMount

这个很简单,就是为了防止每次写useEffect时候写空数组。

 const useMount = (callback) => {
   useEffect(() => {
     callback();
   }, []);
 };

useDebounce

节流函数结合hook使用,利用useEffect的依赖值变化的特性,来控制清空定时器。这里主要应用场景是参数快速变化时候的发送请求的节流处理。

这里看出自定义hook的必要性主要体现在如果需要利用其他hook就可以自定义,如果无法利用其他hook的话就不要滥用自定义hook。

 export const useDebounce = <T>(value: T, delay: number) => {
   const [debounceValue, setDebounceValue] = useState(value);
   useEffect(() => {
     // 每次在value变化以后,设置一个定时器
     const timeout = setTimeout(() => setDebounceValue(value), delay);
     // 上一个useEffect处理完后清理
     return () => clearTimeout(timeout);
   }, [value, delay]);
   return debounceValue;
 }