반응형
다음과 같이 Node 서버에서 약 10초가 걸리는 작업이 있다고 가정하자.
const express = require("express");
const router = express.Router();
let progress = 0;
router.get("/progress", (req, res) => {
res.json({ progress });
});
router.get("/performTask", (req, res) => {
progress = 0; // 작업 초기화
progressInterval = setInterval(() => {
progress += 1;
console.log({ progress });
if (progress > 100) {
progress = 100;
clearInterval(progressInterval); // 작업이 완료되면 인터벌 종료
}
}, 100); // 0.1초마다 작업 수행
res.send({ result: "Task Start..." });
});
module.exports = router;
리액트에서 작업의 진행 상황을 확인해 보자.
구현
리액트에서는 현재 작업 진행 상황(progress)와 작업 시작/종료 여부(isWorking) 변수가 필요하다.
const [progress, setProgress] = useState(0);
const [isWorking, setIsWorking] = useState(false);
서버의 진행 상황을 알 수 있도록 서버에 구현을 해 두었기 때문에 (/progress 라우터)
리액트는 interval 마다 진행 상황을 물어보면서 progress를 갱신하면 된다.
작업이 시작(isWorking = true)되면 useEffect에서 progress를 갱신하면 된다.
useEffect(() => {
let intervalId;
const fetchProgress = async () => {
try {
const response = await axios.get(
"http://192.168.55.120:3002/router_test/progress"
);
setProgress(response.data.progress);
console.log(response.data.progress)
// 작업이 완료되면 인터벌 제거
if (response.data.progress === 100) {
clearInterval(intervalId);
setProgress(false);
setIsWorking(false);
}
} catch (error) {
console.error("Error fetching progress:", error);
}
};
// 작업이 진행 중이면 주기적으로 응답을 확인하는 인터벌 설정
if (isWorking) {
intervalId = setInterval(fetchProgress, 1000); // 매 초마다 진행 상황을 갱신
}
return () => clearInterval(intervalId); // 컴포넌트가 언마운트될 때 인터벌 제거
}, [isWorking]);
전체 코드는 다음과 같다.
import React, { useState, useEffect } from "react";
import axios from "axios";
const Loading = () => {
const [progress, setProgress] = useState(0);
const [isWorking, setIsWorking] = useState(false);
useEffect(() => {
let intervalId;
const fetchProgress = async () => {
try {
const response = await axios.get("YOUR_SERVER_IP/progress");
setProgress(response.data.progress);
console.log(response.data.progress)
// 작업이 완료되면 interval 종료
if (response.data.progress === 100) {
clearInterval(intervalId);
setProgress(false);
setIsWorking(false);
}
} catch (error) {
console.error("Error fetching progress:", error);
}
};
// 작업이 진행 중이면 주기적으로 응답을 확인하는 인터벌 설정
if (isWorking) {
intervalId = setInterval(fetchProgress, 1000); // 매 초마다 진행 상황을 갱신
}
return () => clearInterval(intervalId); // 컴포넌트가 언마운트될 때 인터벌 제거
}, [isWorking]);
const startTask = async () => {
try {
setIsWorking(true);
await axios.get("YOUR_SERVER_IP/performTask");
} catch (error) {
console.error("Error starting task:", error);
}
};
return (
<div>
<button onClick={startTask} disabled={isWorking}>
{isWorking ? "Task in progress..." : "Start Task!!"}
</button>
<p>Progress: {progress}%</p>
</div>
);
};
export default Loading;
반응형
'개발 > React' 카테고리의 다른 글
리액트 - 파일 브라우저 만들기 (React File Browser with chonky) (0) | 2024.03.16 |
---|---|
리액트 - Context API로 상태 관리하기 (Managing State with Context API) (0) | 2024.03.15 |
리액트 - crypto-js로 문자열 암호화/복호화하기 (Encrypting/Decrypting String) (0) | 2024.02.28 |
리액트 - module.css로 CSS 스타일 관리하기 (0) | 2024.02.21 |
리액트 Material - Alert로 플로팅 메시지 만들기 (Floating / Toast Message with Mui Alert) (0) | 2024.02.03 |
댓글