import { Button } from "antd";
import { useCountDown } from "./useCountDown.tsx";
export default function App() {
const [time, startTime, canEdit, text] = useCountDown(5, "캡차 가져오기");
return (
<div className="App">
<Button onClick={startTime} type="primary" disabled={!canEdit}>
{text}
</Button>
</div>
);
}
import { useEffect, useRef, useState } from "react";
export const useCountDown = (initTime: number, initText: string) => {
const [time, setTime] = useState(initTime);
const [canEdit, setCanEdit] = useState(true);
const [text, setText] = useState(initText);
const timerRef: any = useRef();
useEffect(() => {
if (time < 0) {
clearInterval(timerRef.current);
setCanEdit(true);
setText(initText);
} else {
if (time < initTime) {
setText(`검색 (${time}s)`);
}
}
}, [time]);
useEffect(() => {
// 컴포넌트가 파괴되면 타이머를 지워야 합니다.
// 위의 사용 효과에서 효과가 지워지면 커밋 단계의 변이 하위 단계에서 반환 콜백 메서드를 호출하여 타이머를 지웁니다.
return () => {
clearInterval(timerRef.current);
};
}, []);
const startTime = () => {
setCanEdit(false);
setText(`검색 (${time}s)`);
if (!timerRef.current) {
timerRef.current = setInterval(() => {
setTime((t) => t - 1);
}, 1000);
}
};
return [time, startTime, canEdit, text];
};