Progress组件的使用

回到文章
<div id="app"></div>
.progress {
    width: 100%;
}
const { useEffect, useState, useRef } = React;

const useAnimationFrame = (callback, running) => {
    const savedCallback = useRef(callback);
    const animationFrameId = useRef(0);

    useEffect(() => {
        savedCallback.current = callback;
    });

    useEffect(() => {
        function tick() {
            if (typeof savedCallback.current === 'function') {
                savedCallback.current();
            }
            if (running) {
                animationFrameId.current = window.requestAnimationFrame(tick);
            }
        }
        if (running) {
            const animationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;
            const cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame;
            animationFrameId.current = animationFrame(tick);

            return () => cancelAnimationFrame(animationFrameId.current);
        }
    }, [running]);
};

const Progress = ({
    startNum = 0,
    endNum = 100,
    step = 1,
    running = true,
    onStart = () => {}, // 开始的回调
    onStep = () => {}, // 每一步的回调
    onEnd = () => {}, // 结束时的回调
}) => {
    const [progress, setProgress] = useState(startNum);

    onStart();
    useAnimationFrame(() => {
        const nextProgress = Math.min(progress + step, endNum);
        if (nextProgress <= endNum) {
            setProgress(nextProgress);
            onStep(nextProgress);
        } else {
            onEnd();
        }
    }, running && progress < endNum);
    return <p>{progress}</p>;
};

const Home = () => {
    const [startNum, setStartNum] = useState(0);
    const endNum = 10000;
    const [count, setCount] = useState(0);
    const [running, setRunning] = useState(false);
    const [step, setStep] = useState(20);
    const [progress, setProgress] = useState(0);

    return (
        <div className="home">
            <Progress running={running} step={step} startNum={startNum} endNum={endNum} onStep={setProgress} />
            <p><progress className="progress" value={progress} max={endNum}></progress></p>
            <div class="manager">
                <p>
                    step: {step} <input type="button" value="-" onClick={() => setStep(Math.max(1, step - 1))} />
                    <input type="button" value="+" onClick={() => setStep(Math.min(100, step + 1))} />
                </p>
                <p>开始:<input type="button" value="start" onClick={() => setRunning(true)} /></p>
                <p>暂停:<input type="button" value="pause" onClick={() => setRunning(false)} /></p>
                <p>切换:<input type="button" value="toggle" onClick={() => setRunning(!running)} /></p>
            </div>
        </div>
    );
};
ReactDOM.render(<Home />, document.getElementById('app'));