useMinimumLoadingTime.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import { useState, useEffect, useRef } from 'react';
  16. /**
  17. * 自定义 Hook:确保骨架屏至少显示指定的时间
  18. * @param {boolean} loading - 实际的加载状态
  19. * @param {number} minimumTime - 最小显示时间(毫秒),默认 1000ms
  20. * @returns {boolean} showSkeleton - 是否显示骨架屏的状态
  21. */
  22. export const useMinimumLoadingTime = (loading, minimumTime = 1000) => {
  23. const [showSkeleton, setShowSkeleton] = useState(loading);
  24. const loadingStartRef = useRef(Date.now());
  25. useEffect(() => {
  26. if (loading) {
  27. loadingStartRef.current = Date.now();
  28. setShowSkeleton(true);
  29. } else {
  30. const elapsed = Date.now() - loadingStartRef.current;
  31. const remaining = Math.max(0, minimumTime - elapsed);
  32. if (remaining === 0) {
  33. setShowSkeleton(false);
  34. } else {
  35. const timer = setTimeout(() => setShowSkeleton(false), remaining);
  36. return () => clearTimeout(timer);
  37. }
  38. }
  39. }, [loading, minimumTime]);
  40. return showSkeleton;
  41. };