如何自己做网站界面,wordpress添加分享,手游传奇代理平台,新产品宣传推广策划方案为什么要使用自定义 Hooks
自定义 Hooks 是 React 中一种复用逻辑的机制#xff0c;通过它们可以抽离组件中的逻辑#xff0c;使代码更加简洁、易读、易维护。它们可以在多个组件中复用相同的逻辑#xff0c;减少重复代码。
1、useThrottle
代码
import React,{ useRef,…为什么要使用自定义 Hooks
自定义 Hooks 是 React 中一种复用逻辑的机制通过它们可以抽离组件中的逻辑使代码更加简洁、易读、易维护。它们可以在多个组件中复用相同的逻辑减少重复代码。
1、useThrottle
代码
import React,{ useRef, useState,useEffect } from react;/*** useThrottle一个节流的 hook用于限制状态更新的频率。** param {any} initialState 初始状态* param {number} delay 节流间隔时间默认为 500 毫秒* returns {any} 节流后的状态*/
export const useThrottle (initialState, delay 5000) {const [state, setState] useState(initialState);const timeout useRef();const nextValue useRef(null);const hasNextValue useRef(false);useEffect(() {if (timeout.current) {nextValue.current initialState;hasNextValue.current true;} else {setState(initialState);const timeoutCallback () {if (hasNextValue.current) {setState(nextValue.current);hasNextValue.current false;}timeout.current undefined;};timeout.current setTimeout(timeoutCallback, delay);}return () {timeout.current clearTimeout(timeout.current);}}, [initialState]);return state;
};用法
import { useThrottle } from ./useThrottle;const value useThrottle(state, 500);2、useVirtual
代码
import { useEffect, useState } from react;/*** useVirtual一个虚拟滚动的 hook用于优化长列表的渲染性能。** param {object} listRef 列表的引用对象* param {Array} list 初始列表数据* param {boolean} isFullScreen 是否全屏显示* returns {Array} 显示在视图中的列表数据和 padding 样式*/
export const useVirtual (listRef, list, isFullScreen) {const origin list;let viewHeight null;let itemHeight 0;let dur 0;const rootFontSize parseInt(document.documentElement.style.fontSize);const [viewList, setViewList] useState(list);const [startIndex, setStartIndex] useState(0);const [endIndex, setEndIndex] useState(0);const [padding, setPadding] useState({paddingTop: 0,paddingBottom: 0,});useEffect(() {init(listRef);}, []);useEffect(() {initData(listRef.current);update();}, [startIndex]);function init(ref) {initData(ref.current);render(startIndex, dur 1);eventBind(ref.current);}function initData(dom) {const target isFullScreen ? document.documentElement : dom;viewHeight isFullScreen ? target.offsetHeight : target.parentNode.offsetHeight;itemHeight target.getElementsByClassName(virtual-item)[0].offsetHeight;dur Math.floor(viewHeight / itemHeight);}function eventBind(dom) {const eventTarget isFullScreen ? window : dom.parentNode;eventTarget.addEventListener(scroll, handleScroll, false);}function render(startIndex, endIndex) {setViewList(() origin.slice(startIndex, endIndex));setEndIndex(() startIndex dur 1);}function handleScroll(e) {e.stopPropagation();const target isFullScreen ? document.documentElement : listRef.current.parentNode;setStartIndex(() Math.floor(target.scrollTop / itemHeight));}function update() {if (startIndex endIndex) return;setEndIndex(() startIndex dur);render(startIndex, endIndex);setPadding(() {return {paddingTop: (startIndex * itemHeight) / rootFontSize,paddingBottom: ((origin.length - endIndex) * itemHeight) / rootFontSize,};});}return [viewList, padding];
};用法
import { useRef } from react;
import { useVirtual } from ./useVirtual;const listRef useRef();
const [viewList, padding] useVirtual(listRef, initialList, false);3、useCopyToClipboard
代码
import { message } from antd;/*** useCopyToClipboard一个 hook用于复制文本到剪贴板。** returns {Array} 包含单个函数 handleCopy用于复制文本到剪贴板*/
const useCopyToClipboard () {function handleCopy(text) {if (text) {let input document.createElement(input);input.type text;input.value text;input.style.position fixed;input.style.opacity 0;document.body.appendChild(input);input.select();if (document.execCommand(copy)) {message.success(复制成功);} else {message.error(复制失败);}document.body.removeChild(input);} else {message.error(复制失败);}}return [handleCopy];
};export default useCopyToClipboard;用法
import useCopyToClipboard from ./useCopyToClipboard;const [handleCopy] useCopyToClipboard();const copyText () {handleCopy(需要复制的文本);
};4、useSmoothEnter
代码
import { useState, useEffect, useRef } from react;/*** useSmoothEnter一个 hook在 DOM 元素进入视口时添加平滑的进入动画。** returns {object} ref - 一个可以附加到 DOM 元素的 ref 对象用于动画效果*/
const useSmoothEnter () {const ref useRef(null);const [isVisible, setIsVisible] useState(false);const [animationStyle, setAnimationStyle] useState({animation: ,animationPlayState: paused,});useEffect(() {const observer new IntersectionObserver((entries) {const [entry] entries;setIsVisible(entry.isIntersecting);});const element ref.current;if (element) {observer.observe(element);return () {observer.unobserve(element);};}}, [ref]);useEffect(() {if (isVisible) {setAnimationStyle({animation: enterAnimation 1s ease,animationPlayState: running,});}}, [isVisible]);useEffect(() {const element ref.current;if (element) {element.style.animation animationStyle.animation;element.style.animationPlayState animationStyle.animationPlayState;}}, [animationStyle]);return ref;
};export default useSmoothEnter;用法
import useSmoothEnter from ./useSmoothEnter;const ref useSmoothEnter();return div ref{ref} classNameanimated-element内容/div;