1. 异步加载数据Hooks
首先,创建一个名为 AsyncDataLoader.tsx 的文件,其中包含 AsyncDataLoader 组件的代码:
import React from 'react';
import useAsyncData from './useAsyncData'; // 导入自定义 Hook
function AsyncDataLoader({ fetchFunction, render }) {
const { data, isLoading, error } = useAsyncData(fetchFunction);
if (isLoading) {
return (
<div className="loading-overlay">
<div className="loading-spinner"></div>
</div>
);
}
if (error) {
return <div>Error: {error.message}</div>;
}
return render(data);
}
export default AsyncDataLoader;
接下来,创建一个名为 useAsyncData.ts 的文件,其中包含 useAsyncData 自定义 Hook 的代码:
// useAsyncData.js
import { useState, useEffect } from 'react';
// 自定义 Hook:用于获取异步加载的数据
function useAsyncData(fetchFunction) {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
async function fetchData() {
try {
setIsLoading(true);
setError(null);
const result = await fetchFunction();
setData(result);
} catch (error) {
setError(error as Error);
} finally {
setIsLoading(false);
}
}
fetchData();
}, [fetchFunction]);
return { data, isLoading, error };
}
export default useAsyncData;
现在,你可以在主应用文件中导入 AsyncDataLoader 组件并使用它:
import React, {useState, useEffect, FC} from 'react'
// hooks
function useAsyncData (fetchFunction: any) {
const [data, setData] = useState<null|any>(null)
const [isLoading, setIsLoading] = useState(true)
const [error, setError] = useState<null|any>(null)
useEffect(() => {
//组件挂载后异步执行
async function fetchData() {
try {
// 设置loading
setIsLoading(true)
setError(null)
const result = await fetchFunction()
//更新数据
setData(result)
} catch(error) {
setData(error)
} finally {
setIsLoading(false)
}
}
fetchData()
},[fetchFunction])
return {data, isLoading, error}
}
export default useAsyncData
这样,你的组件和自定义 Hook 现在都位于单独的文件中,提高了代码的可读性和维护性,并且使组件可以在应用的不同部分重复使用。希望这对你有所帮助!如果你有其他问题或需要进一步的帮助,请随时提问。
然后,你可以在 AsyncDataLoader.css 文件中定义样式,如下所示:
/* AsyncDataLoader.css */
/* 遮罩屏幕 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
/* 加载动画 */
.loading-spinner {
border: 4px solid rgba(255, 255, 255, 0.3);
border-radius: 50%;
border-top: 4px solid #007bff;
width: 40px;
height: 40px;
animation: spin 1s linear infinite;
}
/* 错误消息 */
.error-message {
color: red;
}
上面的 CSS 样式定义了遮罩屏幕、加载动画和错误消息的外观。你可以根据需要进行自定义样式。
确保将 AsyncDataLoader.css 文件与 AsyncDataLoader.js 放在同一目录下,以确保样式能够正确加载。
2. useLocalStorage Hook-本地缓存
// hooks/useLocalStorage.js
import { useState } from 'react';
/**
* @function useLocalStorage
* @param {string} key - 存储在localStorage中的键名
* @param {any} initialValue - 初始值
* @returns {object} - 包含存储值和更新存储值的函数
*/
function useLocalStorage(key, initialValue) {
// 从localStorage中获取存储值,如果不存在则使用初始值
const [storedValue, setStoredValue] = useState(() => {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
});
// 更新存储值并同步到localStorage
const setValue = (value) => {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
};
return [storedValue, setValue];
}
export default useLocalStorage;
3. useAuthentication Hook-用户鉴权
// hooks/useAuthentication.js
import { useState } from 'react';
/**
* @function useAuthentication
* @returns {object} - 包含用户身份认证状态和登录/注销函数
*/
function useAuthentication() {
const [authenticated, setAuthenticated] = useState(false);
const login = () => {
setAuthenticated(true);
};
const logout = () => {
setAuthenticated(false);
};
return { authenticated, login, logout };
}
export default useAuthentication;
4.useModal Hook -- 开关状态
import { useState } from 'react';
/**
* @function useModal
* @returns {object} - 包含模态框状态和打开/关闭模态框函数
*/
function useModal() {
const [isOpen, setIsOpen] = useState(false);
const openModal = () => {
setIsOpen(true);
};
const closeModal = () => {
setIsOpen(false);
};
return { isOpen, openModal, closeModal };
}
export default useModal;
5.useNotification Hook --通知消息
// hooks/useNotification.js
import { useState } from 'react';
/**
* @function useNotification
* @returns {object} - 包含通知消息和显示/隐藏通知函数
*/
function useNotification() {
const [message, setMessage] = useState(null);
const showMessage = (text) => {
setMessage(text);
};
const hideMessage = () => {
setMessage(null);
};
return { message, showMessage, hideMessage };
}
export default useNotification;
6. useGeoLocation Hook --地理位置
// hooks/useGeoLocation.js
import { useState, useEffect } from 'react';
/**
* @function useGeoLocation
* @returns {object} - 包含地理位置信息和获取地理位置函数
*/
function useGeoLocation() {
const [location, setLocation] = useState(null);
useEffect(() => {
navigator.geolocation.getCurrentPosition((position) => {
setLocation(position.coords);
});
}, []);
return { location };
}
export default useGeoLocation;
7.useLocalStorageList Hook --缓存列表
// hooks/useLocalStorageList.js
import { useState, useEffect } from 'react';
/**
* @function useLocalStorageList
* @param {string} key - 存储在localStorage中的键名
* @param {array} initialValue - 初始值
* @returns {object} - 包含列表数据和更新列表数据的函数
*/
function useLocalStorageList(key, initialValue) {
const [list, setList] = useState(() => {
const storedList = window.localStorage.getItem(key);
return storedList ? JSON.parse(storedList) : initialValue;
});
useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(list));
}, [list, key]);
const addItem = (item) => {
setList([...list, item]);
};
const removeItem = (index) => {
const updatedList = [...list];
updatedList.splice(index, 1);
setList(updatedList);
};
return { list, addItem, removeItem };
}
export default useLocalStorageList;
8.useWebSocket Hook-- 长连接
// hooks/useWebSocket.js
import { useState, useEffect } from 'react';
/**
* @function useWebSocket
* @param {string} url - WebSocket连接URL
* @returns {object} - 包含WebSocket连接状态和消息处理函数
*/
function useWebSocket(url) {
const [socket, setSocket] = useState(null);
useEffect(() => {
const newSocket = new WebSocket(url);
newSocket.onopen = () => {
console.log('WebSocket connected');
};
newSocket.onmessage = (event) => {
// 处理接收到的消息
};
newSocket.onclose = () => {
console.log('WebSocket disconnected');
};
setSocket(newSocket);
return () => {
newSocket.close();
};
}, [url]);
const sendMessage = (message) => {
if (socket && socket.readyState === WebSocket.OPEN) {
socket.send(message);
}
};
return { sendMessage };
}
export default useWebSocket;
9.useMediaQuery Hook --媒体查询
javascriptCopy code// hooks/useMediaQuery.js
import { useState, useEffect } from 'react';
/**
* @function useMediaQuery
* @param {string} query - 媒体查询字符串
* @returns {boolean} - 是否匹配媒体查询
*/
function useMediaQuery(query) {
const [matches, setMatches] = useState(false);
useEffect(() => {
const mediaQuery = window.matchMedia(query);
setMatches(mediaQuery.matches);
const updateMatches = (event) => {
setMatches(event.matches);
};
mediaQuery.addListener(updateMatches);
return () => {
mediaQuery.removeListener(updateMatches);
};
}, [query]);
return matches;
}
export default useMediaQuery;
10. useDebounce Hook --防抖
// hooks/useDebounce.js
import { useState, useEffect } from 'react';
/**
* @function useDebounce
* @param {any} value - 要防抖的值
* @param {number} delay - 防抖延迟时间(毫秒)
* @returns {any} - 防抖后的值
*/
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(handler);
};
}, [value, delay]);
return debouncedValue;
}
export default useDebounce;
11.useDarkMode Hook --系统模式
// hooks/useDarkMode.js
import { useState, useEffect } from 'react';
/**
* @function useDarkMode
* @returns {boolean} - 是否处于暗模式
*/
function useDarkMode() {
const [isDarkMode, setIsDarkMode] = useState(false);
useEffect(() => {
// 根据系统或用户设置来检测暗模式
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)');
setIsDarkMode(prefersDarkMode.matches);
// 监听系统设置的变化
const darkModeListener = (event) => {
setIsDarkMode(event.matches);
};
prefersDarkMode.addListener(darkModeListener);
return () => {
prefersDarkMode.removeListener(darkModeListener);
};
}, []);
return isDarkMode;
}
export default useDarkMode;
12.useProductInventory Hook --库存查询
javascriptCopy code// hooks/useProductInventory.js
import { useState, useEffect } from 'react';
/**
* @function useProductInventory
* @param {string} productId - 产品ID
* @returns {object} - 包含产品库存信息和更新库存的函数
*/
function useProductInventory(productId) {
const [inventory, setInventory] = useState(0);
useEffect(() => {
// 从API获取产品库存信息并更新状态
const fetchProductInventory = async () => {
try {
const response = await fetch(`/api/inventory/${productId}`);
const data = await response.json();
setInventory(data.inventory);
} catch (error) {
console.error('Error fetching product inventory:', error);
}
};
fetchProductInventory();
}, [productId]);
const updateInventory = (newInventory) => {
setInventory(newInventory);
};
return { inventory, updateInventory };
}
export default useProductInventory;
13.useOrderManagement Hook --订单获取
javascriptCopy code// hooks/useOrderManagement.js
import { useState, useEffect } from 'react';
/**
* @function useOrderManagement
* @returns {object} - 包含订单列表、创建订单和更新订单状态的函数
*/
function useOrderManagement() {
const [orders, setOrders] = useState([]);
useEffect(() => {
// 从API获取订单列表并更新状态
const fetchOrders = async () => {
try {
const response = await fetch('/api/orders');
const data = await response.json();
setOrders(data.orders);
} catch (error) {
console.error('Error fetching orders:', error);
}
};
fetchOrders();
}, []);
const createOrder = (newOrder) => {
// 创建新订单并更新状态
// 发送新订单到API
// 更新状态
};
const updateOrderStatus = (orderId, newStatus) => {
// 更新订单状态并更新状态
// 发送状态更新到API
// 更新状态
};
return { orders, createOrder, updateOrderStatus };
}
export default useOrderManagement;