본문 바로가기
개발/React

리액트 - Node 서버 작업 진행 상황 확인하기 (Checking Progress of Node Server Task)

by 피로물든딸기 2024. 3. 15.
반응형

리액트 전체 링크

 

다음과 같이 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;
반응형

댓글