Taeyoung Kim

Engineering

React 핵심 개념 정리: API 연동부터 스타일링까지

React 핵심 개념 정리: API 연동부터 스타일링까지 학습 내용을 정리한 백필 노트입니다.

이 글은 2025년 학습 기록을 블로그 형식으로 정리한 백필 노트입니다.


이 문서는 React의 주요 기능인 useEffect 훅, 조건부 렌더링, CSS 모듈을 사용한 스타일링 방법과 JSON Server를 활용한 API 연동(생성, 수정, 삭제) 방법에 대한 실습 중심의 학습 내용을 요약한 것입니다.

챕터 1. React 생명주기: useEffect

useEffect는 React 컴포넌트가 외부 세계와 상호작용(Side Effect)할 수 있게 돕는 강력한 훅입니다.

  • Side Effect (부수 효과)란?
    • 컴포넌트의 주 역할(UI 렌더링) 외에 발생하는 부수적인 작업들을 의미합니다.
    • 예시: API 호출, 구독 설정, 타이머, DOM 직접 조작 등
  • useEffect의 필요성
    • 컴포넌트가 렌더링될 때마다 Side Effect 코드가 불필요하게 반복 실행되는 것을 방지합니다.
    • 원하는 시점(마운트, 특정 값 변경 등)에만 코드를 실행할 수 있도록 제어합니다.
  • 기본 형태: useEffect(콜백 함수, [종속성 배열])
    • 콜백 함수: 실행하고자 하는 Side Effect 코드를 작성합니다.
    • 종속성 배열:
      • [] (빈 배열): 컴포넌트가 처음 마운트(생성)될 때 한 번만 실행됩니다. (API 최초 호출 시 주로 사용)
      • 생략 시: 렌더링될 때마다 실행되어 무한 루프 위험이 있습니다.
      • [value]: 배열 안의 value가 변경될 때마다 실행됩니다.
  • 실습 요약:
    • PostList.js 컴포넌트를 생성합니다.
    • useStateposts, isLoading, error 상태를 관리합니다.
    • useEffect를 사용해 컴포넌트 마운트 시 JSONPlaceholder API로부터 게시글 데이터를 fetch로 가져옵니다.
    • 데이터 로딩 중, 성공, 오류 발생 각 상태에 따라 다른 UI를 화면에 표시합니다.
    • 종속성 배열의 중요성을 무한 루프 발생 실습을 통해 확인합니다.

챕터 2. React 조건부 렌더링

조건부 렌더링은 특정 조건의 참/거짓에 따라 다른 UI를 화면에 보여주는 기술입니다.

  • 주요 방법:
    1. if: 함수 컴포넌트의 return 문 이전에 사용하여 조건에 따라 완전히 다른 JSX를 반환할 때 유용합니다.
    2. 논리 연산자 &&: 조건 && <JSX> 형태로, 조건이 true일 때만 JSX를 렌더링합니다.
    3. 삼항 연산자 ? :: 조건 ? <JSX A> : <JSX B> 형태로, 조건에 따라 두 가지 다른 JSX 중 하나를 선택하여 렌더링합니다.
  • 실습 요약:
    • DataFetcher.js 컴포넌트를 생성하고, loading, success, error 세 가지 상태를 useState로 관리합니다.
    • useEffectsetTimeout을 사용하여 데이터 로딩 성공/실패 상황을 시뮬레이션합니다.
    • if 문을 사용하여 각 상태(loading, error, success)에 따라 다른 화면 전체를 반환하는 로직을 구현합니다.
    • 성공 화면 내에서 && 연산자를 사용해 부가 정보를 조건부로 표시합니다.
    • ? : 연산자를 사용해 상태에 따라 다른 아이콘이나 메시지를 동적으로 선택하여 표시합니다.

챕터 3. React에서 API 호출하기 (심화)

React 컴포넌트 내에서 외부 서버와 통신하여 데이터를 요청하고 화면에 표시하는 방법을 심도 있게 다룹니다.

  • 핵심 개념:
    • 비동기 작업: 시간이 걸리는 API 호출 같은 작업을 프로그램의 흐름을 막지 않고 처리하는 방식입니다.
    • API: 다른 소프트웨어와 데이터를 주고받기 위한 규칙과 방법의 집합입니다.
    • useEffect: 컴포넌트가 화면에 나타난 후 API를 호출하는 등 Side Effect를 처리하는 데 사용됩니다.
  • 실습 요약:
    • 데이터 준비: useState를 사용해 데이터를 저장할 posts, 로딩 상태 isLoading, 오류 상태 error 변수를 만듭니다.
    • API 호출: useEffect 안에서 fetch API를 사용하여 JSONPlaceholder의 데이터를 비동기적으로 요청합니다.
    • 상태 업데이트: .then() 또는 async/await 구문을 사용하여 성공적으로 받아온 데이터를 setPosts로 상태에 저장하고, 로딩 상태를 false로 변경합니다.
    • 오류 처리: .catch() 또는 try...catch 구문을 사용하여 통신 중 발생한 오류를 error 상태에 저장합니다.
    • 화면 표시: map 함수를 사용하여 상태에 저장된 데이터 배열을 순회하며 각 항목을 <li> 태그로 렌더링하고, 로딩 및 오류 상태에 따라 적절한 메시지를 표시합니다.

챕터 4. 스타일링 방법: CSS 모듈

CSS 모듈은 컴포넌트별로 스타일을 독립적으로 관리하여 클래스 이름 충돌 문제를 해결하는 방법입니다.

  • 핵심 원리:
    • 파일 이름을 .module.css로 작성하면, 빌드 과정에서 각 클래스 이름이 고유한 문자열(예: title_abc12)로 자동 변환됩니다.
    • 이를 통해 다른 컴포넌트에서 같은 클래스 이름을 사용해도 스타일이 서로에게 영향을 주지 않습니다.
  • 사용 방법:
    1. Button.module.css와 같이 파일을 생성하고 스타일을 정의합니다.
    2. import styles from './Button.module.css';와 같이 JavaScript 파일에서 객체로 가져옵니다.
    3. <button className={styles.primary}>처럼 객체의 속성으로 접근하여 클래스를 적용합니다.
  • 실습 요약:
    • ButtonTitle 컴포넌트 및 각각의 .module.css 파일을 생성합니다.
    • 두 CSS 파일에 동일한 primary 클래스 이름을 정의하여 각 컴포넌트에 적용해도 스타일이 충돌하지 않음을 확인합니다.
    • props를 받아 조건부로 다른 스타일(styles.warning)을 적용하는 방법을 실습합니다.
    • 백틱(```)을 사용하여 하나의 요소에 여러 클래스(className={\${styles.button} ${styles.primary}})를 동시에 적용합니다.

챕터 5. JSON Server 설정하기

JSON Server는 실제 백엔드 없이 db.json 파일 하나로 REST API Mock 서버를 손쉽게 구축할 수 있는 도구입니다.

  • 설치 및 실행:
    1. npm install -g json-server 명령어로 전역 설치합니다.
    2. 프로젝트 폴더에 db.json 파일을 생성하고 초기 데이터를 JSON 형식으로 작성합니다.
    3. json-server --watch db.json --port 5000 명령어로 서버를 실행합니다. (-watch는 파일 변경 시 자동 재시작 옵션)
  • 주요 기능:
    • db.json의 최상위 키(예: "todos")를 기반으로 API 엔드포인트(예: http://localhost:5000/todos)를 자동으로 생성합니다.
    • GET, POST, PUT, DELETE 등 기본적인 REST API 요청을 모두 지원합니다.
    • 웹 브라우저나 curl 명령어로 데이터를 쉽게 조회하고 테스트할 수 있습니다.
  • 실습 요약:
    • json-server를 설치하고 db.json 파일에 todosusers 데이터를 추가합니다.
    • 서버를 실행하고 웹 브라우저 주소창에 http://localhost:포트번호/todos.../todos/1을 입력하여 전체 및 개별 데이터 조회를 확인합니다.
    • db.json 파일을 수정하면 서버가 자동으로 변경 사항을 반영하는 것을 확인합니다.

챕터 6. React에서 데이터 생성하기 (POST)

React 앱에서 사용자가 입력한 데이터를 서버에 새로 생성(저장)하는 방법을 배웁니다.

  • 핵심 개념:
    • HTTP POST: 서버에 새로운 리소스(데이터)를 생성할 때 사용하는 요청 메서드입니다.
    • fetch POST 요청: fetch(url, options)에서 options 객체에 다음을 설정합니다.
      • method: 'POST'
      • headers: { 'Content-Type': 'application/json' }: 보내는 데이터가 JSON 형식임을 명시합니다.
      • body: JSON.stringify(data): JavaScript 객체를 JSON 문자열로 변환하여 본문에 담아 보냅니다.
  • 실습 요약:
    • AddNoteForm 컴포넌트를 만들고 inputbutton이 있는 form을 구성합니다.
    • useState로 입력 값을 관리하고, onSubmit 이벤트 핸들러(handleSubmit)를 연결합니다.
    • handleSubmit 함수 내에서 e.preventDefault()로 페이지 새로고침을 방지합니다.
    • 입력 값을 객체로 만든 후 JSON.stringify를 사용하여 fetchbody에 담아 JSON Server로 POST 요청을 보냅니다.
    • 요청 성공 후, 입력 필드를 비우고 부모 컴포넌트로부터 props로 받은 콜백 함수를 실행하여 전체 목록을 새로고침합니다.
    • isAdding 상태를 추가하여 요청 중에 버튼을 비활성화하는 등 사용자 경험(UX)을 개선합니다.

챕터 7. React에서 데이터 수정/삭제하기 (PUT/DELETE)

서버에 이미 저장된 데이터를 수정하거나 삭제하는 방법을 배웁니다.

  • 핵심 개념:
    • HTTP DELETE: 특정 ID를 가진 리소스를 삭제할 때 사용합니다. fetch('/todos/1', { method: 'DELETE' })와 같이 요청하며 보통 body가 필요 없습니다.
    • HTTP PUT: 특정 ID를 가진 리소스 전체를 새로운 데이터로 교체(수정)할 때 사용합니다. fetch('/todos/1', { method: 'PUT', ... })와 같이 요청하며, POST와 유사하게 수정할 데이터를 body에 담아 보냅니다.
  • 실습 요약 (삭제):
    1. 각 항목에 '삭제' 버튼을 추가하고 onClick 이벤트에 handleDeleteTodo(id)를 연결합니다.
    2. handleDeleteTodo 함수에서 fetch를 사용하여 해당 id의 URL로 method: 'DELETE' 요청을 보냅니다.
    3. 요청 성공 시, setTodos(todos.filter(todo => todo.id !== id)) 코드로 UI 상태에서 해당 항목을 제거합니다.
  • 실습 요약 (수정):
    1. editingId, editingText 상태를 추가하여 '수정 모드'를 관리합니다.
    2. '수정' 버튼 클릭 시 editingId를 설정하여 UI를 입력창으로 변경합니다.
    3. '저장' 버튼 클릭 시 handleUpdateTodo 함수에서 fetch를 사용하여 해당 id의 URL로 method: 'PUT' 요청을 보냅니다. (수정된 전체 객체를 body에 담음)
    4. 요청 성공 시, setTodos(todos.map(todo => todo.id === id ? updatedData : todo)) 코드로 UI 상태를 업데이트하고 setEditingId(null)로 수정 모드를 종료합니다.