(고객 관리 시스템 개발 강의) 9강 - React의 라이프 사이클 이해 및 API 로딩 처리 구현하기

IRISH·2024년 6월 13일

PracticeManagement

목록 보기
9/9
post-thumbnail

강의 요약

에러 1 - 'theme' is not defined & 'progress' is not defined

에러 코드 (App.js)

import React, { useState, useEffect } from "react";
import "./App.css";
import Customer from "./components/Customer";
import {
  Paper,
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
  CircularProgress,
} from "@mui/material";
import { styled } from "@mui/system";

// Styled 컴포넌트 정의
const StyledPaper = styled(Paper)({
  width: "100%",
  marginTop: "24px",
  overflow: "auto",
});

const StyledTable = styled(Table)({
  minWidth: 1080,
});

const StyledCircularProgress = styled(Table)({
  margin: theme.spacing.unit * 2,
});

function App() {
  const [customers, setCustomers] = useState("");
  const [completed, setCompleted] = useState(0);

  useEffect(() => {
    const callApi = async () => {
      const response = await fetch("/api/customers");
      const body = await response.json();
      return body;
    };

    callApi()
      .then((res) => setCustomers(res))
      .catch((err) => console.log(err));

    const progress = () => {
      completed >= 100 ? setCompleted(0) : setCompleted(completed + 1);
    };

    this.timer = setInterval(this.progress, 20);
  }, []);
  
  return (
    <StyledPaper>
      <StyledTable>
        <TableHead>
          <TableRow>
            <TableCell>번호</TableCell>
            <TableCell>이미지</TableCell>
            <TableCell>이름</TableCell>
            <TableCell>생년월일</TableCell>
            <TableCell>성별</TableCell>
            <TableCell>직업</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {customers ? (
            customers.map((c) => (
              <Customer
                key={c.id} // map 을 사용하려면 key 라는 속성이 있어야 함(안하면 Console창에 에러가 발생)
                id={c.id}
                image={c.image}
                name={c.name}
                birthday={c.birthday}
                gender={c.gender}
                job={c.job}
              />
            ))
          ) : (
            <TableRow>
              <TableCell colSpan="6" align="center">
                <CircularProgress
                  className={progress}
                  variant="determine"
                  value={this.state.completed}
                />
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </StyledTable>
    </StyledPaper>
  );
}

에러 원인

  • theme 변수가 정의되지 않음
  • progress 변수가 정의되지 않음

에러 해결

  • theme 변수 정의:
    theme 변수는 MUI의 useTheme 훅을 사용하여 가져올 수 있습니다. styled 함수 내부에서 theme를 사용할 수 있도록 StyledCircularProgress 컴포넌트를 수정합니다.
  • progress 변수 정의:
    CircularProgress 컴포넌트의 className에 할당된 progress 변수는 존재하지 않기 때문에 발생하는 오류입니다. 따라서 progress 클래스를 className에 직접 전달하지 않고, completed 상태를 직접 전달하도록 수정합니다.

에러 수정 코드

import React, { useState, useEffect } from "react";
import "./App.css";
import Customer from "./components/Customer";
import {
  Paper,
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
  CircularProgress,
} from "@mui/material";
import { styled, useTheme } from "@mui/system";

// Styled 컴포넌트 정의
const StyledPaper = styled(Paper)({
  width: "100%",
  marginTop: "24px",
  overflow: "auto",
});

const StyledTable = styled(Table)({
  minWidth: 1080,
});

const StyledCircularProgress = styled(CircularProgress)(({ theme }) => ({
  margin: theme.spacing(2),
}));

function App() {
  const [customers, setCustomers] = useState("");
  const [completed, setCompleted] = useState(0);
  const theme = useTheme();

  useEffect(() => {
    const callApi = async () => {
      const response = await fetch("/api/customers");
      const body = await response.json();
      return body;
    };

    callApi()
      .then((res) => setCustomers(res))
      .catch((err) => console.log(err));

    const progress = () => {
      setCompleted((prevCompleted) =>
        prevCompleted >= 100 ? 0 : prevCompleted + 1
      );
    };

    const timer = setInterval(progress, 20);
    return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <StyledPaper>
      <StyledTable>
        <TableHead>
          <TableRow>
            <TableCell>번호</TableCell>
            <TableCell>이미지</TableCell>
            <TableCell>이름</TableCell>
            <TableCell>생년월일</TableCell>
            <TableCell>성별</TableCell>
            <TableCell>직업</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {customers ? (
            customers.map((c) => (
              <Customer
                key={c.id} // map 을 사용하려면 key 라는 속성이 있어야 함(안하면 Console창에 에러가 발생)
                id={c.id}
                image={c.image}
                name={c.name}
                birthday={c.birthday}
                gender={c.gender}
                job={c.job}
              />
            ))
          ) : (
            <TableRow>
              <TableCell colSpan="6" align="center">
                <StyledCircularProgress
                  variant="indeterminate"
                  value={completed}
                />
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </StyledTable>
    </StyledPaper>
  );
}

export default App;

전체 소스 코드

management/client/src/App.js

import React, { useState, useEffect } from "react";
import "./App.css";
import Customer from "./components/Customer";
import {
  Paper,
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
  CircularProgress,
} from "@mui/material";
import { styled, useTheme } from "@mui/system";

// Styled 컴포넌트 정의
const StyledPaper = styled(Paper)({
  width: "100%",
  marginTop: "24px",
  overflow: "auto",
});

const StyledTable = styled(Table)({
  minWidth: 1080,
});

const StyledCircularProgress = styled(CircularProgress)(({ theme }) => ({
  margin: theme.spacing(2),
}));

function App() {
  const [customers, setCustomers] = useState("");
  const [completed, setCompleted] = useState(0);
  const theme = useTheme();

  useEffect(() => {
    const callApi = async () => {
      const response = await fetch("/api/customers");
      const body = await response.json();
      return body;
    };

    callApi()
      .then((res) => setCustomers(res))
      .catch((err) => console.log(err));

    const progress = () => {
      setCompleted((prevCompleted) =>
        prevCompleted >= 100 ? 0 : prevCompleted + 1
      );
    };

    const timer = setInterval(progress, 20);
    return () => {
      clearInterval(timer);
    };
  }, []);

  return (
    <StyledPaper>
      <StyledTable>
        <TableHead>
          <TableRow>
            <TableCell>번호</TableCell>
            <TableCell>이미지</TableCell>
            <TableCell>이름</TableCell>
            <TableCell>생년월일</TableCell>
            <TableCell>성별</TableCell>
            <TableCell>직업</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {customers ? (
            customers.map((c) => (
              <Customer
                key={c.id} // map 을 사용하려면 key 라는 속성이 있어야 함(안하면 Console창에 에러가 발생)
                id={c.id}
                image={c.image}
                name={c.name}
                birthday={c.birthday}
                gender={c.gender}
                job={c.job}
              />
            ))
          ) : (
            <TableRow>
              <TableCell colSpan="6" align="center">
                <StyledCircularProgress
                  variant="indeterminate"
                  value={completed}
                />
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </StyledTable>
    </StyledPaper>
  );
}

export default App;

결과 화면

⇒ 데이터 들어오기 전에 (동영상임)
https://file.notion.so/f/f/f4037768-0bc4-464a-bd49-039592750367/d67aab86-b1a2-4fc9-ace2-2f7ea58e8b9c/Irish_Management_-_Chrome_2024-06-13_23-14-10.mp4?id=1eb2e7e4-f6b8-4b5c-a82b-1bdfb0a2bc05&table=block&spaceId=f4037768-0bc4-464a-bd49-039592750367&expirationTimestamp=1718380800000&signature=NX_HZ0-0ZfncMfsiaY9Qq6RBqbPNVUnUaYrh4L3XjCY

⇒ 데이터가 다 들어왔을 때

profile
#Software Engineer #IRISH

0개의 댓글