继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

前端开发者必会的7个React自定义Hooks 🚀

缥缈止盈
关注TA
已关注
手记 321
粉丝 35
获赞 155

自定义钩子在 React 中可不仅仅是一种便利,它们对模块化和可维护代码来说是个大变革。它们允许开发者封装逻辑、管理状态,并以前所未有的方式简化复杂的功能。

图片描述(这是一张图片,点击可以查看详细内容。)

React 的强大函数式编程范式重新定义了现代前端开发的格局,为构建模块化、易于维护和可重用的代码铺平了道路。在众多功能中,自定义钩子特别突出,是构建更智能、更简洁组件的关键工具。今天,让我们深入了解每个开发者都应该掌握的一些核心自定义钩子,并学习如何有效地实现它们,从而更好地服务开发工作。

此处省略内容

  1. useFetch : 简化 API 调用,让开发更轻松 🌐 Fetching 数据是 React 中一个常见的任务。useFetch 这个钩子抽象了重复的逻辑,使之更加简洁,简化了 API 调用,并优雅地管理状态。

做到:
做到 (如果后面还有其他文字)

    import { useState, useEffect } from "react";

    function useFetch<T>(url: string) {
      const [data, setData] = useState<T | null>(null);
      const [loading, setLoading] = useState(true);
      const [error, setError] = useState<Error | null>(null);

      useEffect(() => {
        const fetchData = async () => {
          setLoading(true);
          try {
            const response = await fetch(url);
            const result = await response.json();
            setData(result);
          } catch (err) {
            setError(err as Error);
          } finally {
            setLoading(false);
          }
        };

        fetchData();
      }, [url]);

      return { data, loading, error };
    }

    //  this hook is used to fetch data from a specified URL and handle loading and error states
    export default useFetch;

点击全屏模式, 点击退出全屏

使用方法

    const { data, loading, error } = useFetch<User[]>('/api/users');

    if (loading) return <p>正在加载...</p>;
    if (error) return <p>错误: {错误信息}</p>;

    return <ul>{data?.map(user => <li key={user.id}>{user.name}</li>)}</ul>;

切换到全屏 退出全屏

此处省略了内容

  1. useDebounce : 性能优化 ⏳ 使用防抖钩子来优化频繁的用户输入,例如搜索或表单字段,减少不必要的渲染和API调用。

实现如下:

导入 { useState, useEffect } from "react";

function useDebounce<T>(value: T, delay: number): T {
  const [debouncedValue, setDebouncedValue] = useState(value);

  useEffect(() => {
    const handler = setTimeout(() => setDebouncedValue(value), delay);

    return () => clearTimeout(handler);
  }, [value, delay]);

  return debouncedValue;
}

导出默认 useDebounce;

切换到全屏模式,或者退出全屏

怎么用:

    const [searchTerm, setSearchTerm] = useState('');
    const debouncedSearch = useDebounce(searchTerm, 500);

    useEffect(() => {
      if (debouncedSearch) {
        // 调用API或其他操作
      }
    }, [debouncedSearch]);

全屏模式,退出全屏

……

  1. useToggle:使用我们定制的 useToggle 钩子,可以轻松管理模态框、下拉菜单或主题切换的布尔值状态,让你的代码保持干净且易于重用。

实施

    import { useState } from "react";

    function useToggle(initialState = false) {
      const [state, setState] = useState(initialState);

      const toggle = () => setState(prev => !prev);

      return [state, toggle];
    }

    export default useToggle;

点击进入全屏模式,点击退出全屏模式

怎么用:

    const [isModalOpen, toggleModal] = useToggle();

    return (
      <div>
        <button onClick={toggleModal}>点击以显示/隐藏模态框</button>
        {isModalOpen && <p>模态框</p>}
      </div>
    );

全屏 / 退出全屏

此处为空

  1. useLocalStorage : 本地存储数据 📂 利用一个自定义的 useLocalStorage 钩子,存储和获取数据变得既简单又实用。

实现:

    import { useState } from "react";

    function useLocalStorage<T>(key: string, initialValue: T) {
      const [storedValue, setStoredValue] = useState<T>(() => {
        try {
          const item = window.localStorage.getItem(key);
          return item ? JSON.parse(item) : initialValue;
        } catch (error) {
          console.error(error);
          return initialValue;
        }
      });

      const setValue = (value: T) => {
        try {
          setStoredValue(value);
          window.localStorage.setItem(key, JSON.stringify(value));
        } catch (error) {
          console.error(error);
        }
      };

      return [storedValue, setValue] as const;
    }

    export default useLocalStorage;

点击进入全屏 点击退出全屏

使用方法:

    const [theme, setTheme] = useLocalStorage('theme', 'light');

    return (
      <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
        切换主题
      </button>
    );

进入全屏 退出全屏

……

  1. usePrevious :跟踪先前状态 📜 在比较和动画中,跟踪值的先前状态非常必要,可以通过自定义 usePrevious 钩子轻松实现这一功能。

实现部分:

这是一个React钩子函数,名为usePrevious,它接收一个泛型参数value,并返回value的前一个值。这个函数使用了React提供的useEffectuseRef钩子。

useRef用于创建一个引用对象,可以用来保存任何值。在这个函数里,我们创建了一个名为ref的引用对象,它是一个包含泛型参数T的类型。useEffect钩子则在value发生变化时执行,将value的当前值赋给ref.current

整个函数的作用是在React组件内部追踪value的前一个值。当调用usePrevious(value)时,它会返回之前value的值。如果这是value第一次被赋值,那么返回值将为undefined

export default usePrevious;表示这个函数是默认导出的,这样其他文件可以导入并使用它。

这是一个简化的解释,适合用于理解代码的功能和用途。

全屏显示 退出全屏

使用方法:

    const [count, setCount] = useState(0);
    const prevCount = usePrevious(count);

    return (
      <p>
        现在是 {count}, 之前的数值是 {prevCount}
      </p>
    );

全屏 退出全屏


  1. useClickOutside : 检测外部点击事件 🖱️ 当点击外部时自动关闭模态框或下拉菜单,使用自定义的 useClickOutside 钩子来以提升用户体验感。

实施:

    import { useEffect, useRef } from "react";

    // 使用点击外部的自定义Hook
    function useClickOutside(handler: () => void) {
      const ref = useRef<HTMLDivElement>(null);

      useEffect(() => {
        const handleClickOutside = (event: MouseEvent) => {
          if (ref.current && !ref.current.contains(event.target as Node)) {
            handler();
          }
        };

        document.addEventListener('mousedown', handleClickOutside);
        return () => document.removeEventListener('mousedown', handleClickOutside);
      }, [handler]);

      return ref;
    }

    export default useClickOutside;

进入全屏模式,退出全屏模式

使用方法:

    const ref = useClickOutside(() => setDropdownOpen(false));

    return (
      <div ref={ref}>
        {dropdownOpen && <p>下拉菜单</p>}
      </div>
    );

点击此处进入全屏模式 点击此处退出全屏


  1. useMediaQuery :使用自定义的 useMediaQuery 钩子可以简化 React 中的媒体查询管理,从而实现更高效的响应式设计。

实施:

    import { useState, useEffect } from "react";

    function useMediaQuery(query: string): boolean {
      const [matches, setMatches] = useState(false);

      useEffect(() => {
        const mediaQueryList = window.matchMedia(query);
        // 使用 matchMedia 检查媒体查询
        const updateMatch = () => setMatches(mediaQueryList.matches);
        updateMatch();
        // 当媒体查询变化时更新匹配状态
        mediaQueryList.addEventListener('change', updateMatch);
        return () => mediaQueryList.removeEventListener('change', updateMatch);
      }, [query]);

      return matches;
    }

    export default useMediaQuery;

进入全屏,退出全屏

使用方法:

const isMobile = useMediaQuery('(max-width: 768px)');

return <p>{isMobile ? '移动视图' : '桌面视图'}</p>;

点击全屏/退出全屏

自定义钩子展示了React的灵活性和强大,使代码更干净、可复用且更容易维护。

通过利用自定义钩子,开发人员可以简化复杂的功能性,并创建可复用且高效的代码。上述示例说明了这些钩子如何优雅地应对常见问题。


希望这对你有帮助!如果你愿意,我们可以在我 LinkedIn 上连接 🚀

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP