custom-hooks

252 阅读1分钟

实现分页请求数据

// 用来请求远程接口,实现分页数据的获取
const URL = 'http://localhist:8000/api/users';
const [data, options, setOptions] = useRequest(URL);
const { totalPage, list } = data;
const { currentPage } = options;

function useRequest(url) {
    // 查询参数
    let [options, setOptions] = useState({
        currentPage: 1,
        pageSize: 5
    });
    // 接口返回的数据
    let [data, setData] = useState({
        totalPage: 0,
        list: []
    });
    // 调用接口 返回数据
    function getData() {
        let { currentPage, pageSize } = options;
        fetch(`${url}?currentPage=${currentPage}&pageSize=${pageSize}`)
        .then(res => res.json())
        .then(res => {
            setData({...res});
        });
    }
    useEffect(getData, [options, url])
    return [data, options, setOptions]
}

拖拽 useDrag

// 使用
import React, { useLayoutEffect } from 'react';
import useDrag from '../hooks/useDrag';
const basicStyle = { width: '100px', height: '100px', borderRadius: '50%'};
export default function Drag() {
    const [style1,dragRef1] = useDrag();
    const [style2,dragRef2] = useDrag();
    return (
        <>
            <div
                ref={dragRef1}
                style={{
                    ...basicStyle,
                    backgroundColor: 'red',
                    transform: `translate(${style1.x}px,${style1.y}px)`
                }}
            ></div>
            <div
                ref={dragRef2}
                style={{
                    ...basicStyle,
                    backgroundColor: 'red',
                    transform: `translate(${style2.x}px,${style2.y}px)`
                }}
            ></div>
        </>
    )
}

function useDrag() {
    // DOM元素的位置
    const positionRef = useRef({
        currentX:0, currentY: 0, // 当前的位置
        lastX: 0, lastY: 0, // 上一次的位置
    });// 存放位置信息
    // 你要让哪个dom元素进行移动
    const domRef = useRef(null); // domRef.current = div真实dom元素
    const [_, forceUpdate] = useState({});
    useLayoutEffect(() => {
        // 拖拽开始的x坐标和y坐标
        let startX,startY;
        const start = function(event) {
            const {clientX, clientY} = event.targetTouches[0];
            startX = clientX;
            startY = clientY;
            domRef.current.addEvenntListener('touchmove', move);
            domRef.current.addEvenntListener('touchend', end);
        }
        const move = function(event) {
            const { clientX, clientY } = event.targetTouches[0];
            positionRef.current.currentX = positionRef.current.lastX + (clientX - startX);
            positionRef.current.currentY = positionRef.current.lastY+(clientY- startY);
            forceUpdate({}); // 调用就更新
        }
        const end = function(event) {
            positionRef.current.lastX = positionRef.current.currentX;
            positionRef.current.lastY = positionRef.current.currentY;
            domRef.current.removeEventListener("touchmove", move);
            domRef.current.removeEventListener("touchend", end);
        }
        domRef.current.addEvenntListener("touchstart", start);
    }, []); // 只会执行一次
    return [
        {
            x: positionRef.current.currentX,
            y: positionRef.current.currentY
        },
        domRef
    ]
}

表单 useForm

function Form() {
    let [formData, setFormValue, resetFormValue] = useForm({username: "", email: ""});
    return (
        <form>
            <div>
                <label>用户名</label>
                <input
                    value={formData.username}
                    onChange={(event) => setFormValue('username', event.target.value)}
                />
            </div>
            <div>
                <label>邮箱</label>
                <input
                    value={formData.email}
                    onChange={(event) => setFormValue('email', event.target.value)}
                />
            </div>
            <button
                onClick={() => console.log(formData)}
            >提交</button>
            <button
                onClick={() => resetFormValue()}
            >重置</button>
        </form>
    )
}

function useForm(initialValues) {
    const [formData, setFormData] = useState(initialValues);
    const setFormValue = (key, value) => {
        setFormData({
            ...formData,
            [key]: value
        })
    }
    const resetFormValue = () => {
        setFormData(initialValues)
    }
    return [formData, setFormValue, resetFormValue];
}

useAnimation

  • 动画的核心是更改类名
function Animation() {
    const [className, toggle] = useAnimation('circle', 'active');
    return <div className={className} onClick={toggle}></div>
}

function useAnimation(baseClassName, activeClassName) {
    const [className, setClassName] = useState(baseClassName);
    const toggle = () => {
        if(className === baseClassName) {
            setClassName(`${baseClassName} ${activeClassName}`)
        } else {
            setClassName(`${baseClassName}`)
        }
    }
    return [className, toggle];
}