LogoSEO Jing
  • All Posts
  • SEO Jing
  • okayJing
  • KD Team
  • CLab CoreTeam
  • Study

Contact Me

© 2026 SEOJing. All rights reserved.

프론트엔드스터디React상태관리생명주기사전진단

사전 진단 퀴즈 5단계 (선언적 UI와 상태)

2026년 3월 19일·8분 읽기

서론: 자바스크립트를 넘어, 리액트적 사고방식 장착하기

프론트엔드 스터디 사전 진단 퀴즈의 마지막 5단계입니다. 지금까지 HTML, CSS, 그리고 자바스크립트의 핵심 개념을 짚어보았다면, 이제는 현대 프론트엔드 개발의 표준으로 자리 잡은 리액트의 코어 개념을 확인합니다.

5단계까지 막힘없이 풀어나갔다면, 후에 진행할 스터디를 참여할 이유가 없습니다. 그렇기에 모르는게 당연해요. 프리뷰 느낌으로 가볍게 보고 넘어가는 걸 추천합니다.


질문 1. 선언적 패러다임 (Declarative UI)

질문 의도

명령형(Imperative) 프로그래밍에서 선언형(Declarative) 프로그래밍으로의 사고방식 전환이 이루어졌는지 확인합니다. 이 차이를 온전히 이해해야만 DOM을 직접 건드리는 바닐라 자바스크립트의 습관에서 벗어나, 리액트가 제공하는 가상 돔(Virtual DOM)의 이점을 제대로 누릴 수 있습니다.

문제

바닐라 JS에서는 요소를 화면에 넣으려면 createElement로 만들고 일일이 붙여줘야 합니다. 반면 리액트에서는 단순히 JSX 문법을 작성하기만 하면 됩니다. 이런 방식은 개발자의 DOM 조작 방식을 어떻게 바꿔놓았을까요?

정답 및 풀이

  • 정답: 개발자가 화면을 '어떻게(How)' 그릴지 단계별로 지시하는 대신, 데이터에 따라 화면이 '무엇(What)'을 보여줄지만 선언하도록 방식이 바뀌었습니다.
  • 풀이 과정: 바닐라 자바스크립트는 요소를 찾고, 생성하고, 속성을 부여하고, 화면에 부착하는 모든 과정을 개발자가 직접 제어해야 합니다. 반면 리액트의 선언적 방식에서는 화면의 최종 결과물(JSX)만 정의해 두면, 데이터가 변했을 때 리액트 엔진이 알아서 기존 화면과 새로운 화면을 비교하여 변경된 부분만 실제 DOM에 업데이트해 줍니다.

💡 리액트 연계 포인트

복잡한 웹 애플리케이션에서는 UI 상태가 수시로 변합니다. DOM을 직접 조작하는 코드는 상태 추적을 어렵게 만들고 치명적인 버그를 유발하지만, 선언적 UI는 코드의 가독성을 높이고 유지보수를 매우 쉽게 만들어 줍니다.


질문 2. 상태와 렌더링 (State & Render)

포스트 목록

/study/clab-26-1/preclass
파일 5개, 폴더 0개
사전 진단 퀴즈 1단계 (HTML/CSS)사전 진단 퀴즈 2단계 (HTML/CSS 활용)사전 진단 퀴즈 3단계 (변수와 DOM)사전 진단 퀴즈 4단계 (배열, 함수, 비동기)사전 진단 퀴즈 5단계 (선언적 UI와 상태)

질문 의도

리액트가 화면을 다시 그리는(Re-render) 트리거가 무엇인지 정확히 알고 있는지 묻는 문제입니다. 일반 변수와 리액트 상태의 차이를 모르면 리액트를 배우지 않았다고 해도 무방해요. 이게 가장 큰 장점이기 때문이죠.

문제

사용자가 '좋아요' 버튼을 클릭해서 숫자를 1 올리려고 합니다. 이때 숫자를 일반 변수(let count = 0)로 만들고 1을 더했을 때와, 리액트의 useState를 사용해 변경했을 때 화면에 숫자가 업데이트되는 과정은 어떻게 다를까요?

정답 및 풀이

  • 정답: 일반 변수의 값을 변경하면 내부 데이터만 바뀔 뿐 화면은 업데이트되지 않습니다. 반면 useState의 설정 함수(setter)를 통해 값을 변경하면 리액트가 상태 변화를 감지하고 해당 컴포넌트를 다시 렌더링하여 화면에 변경된 숫자를 반영합니다.
  • 풀이 과정: 리액트 컴포넌트는 기본적으로 자신의 상태(State)나 부모로부터 받은 데이터(Props)가 변경될 때만 새로고침(리렌더링)을 수행합니다. 일반 let 변수는 값이 바뀌어도 리액트 엔진에게 화면을 다시 그리라는 신호를 보내지 못합니다.

💡 리액트 연계 포인트

화면에 보여져야 하는 동적인 데이터는 반드시 useState(또는 다른 상태 관리 도구)로 관리해야 합니다. 반대로 화면에 그릴 필요가 없는 내부적인 타이머 ID나 임시 데이터까지 State로 관리하면 불필요한 렌더링이 발생하여 성능이 저하되므로, 이 둘을 구분하는 것이 최적화에서의 키 포인트입니다.


질문 3. 단방향 데이터 흐름 (Unidirectional Data Flow)

질문 의도

리액트의 핵심 설계 원칙인 '단방향 데이터 흐름'을 이해하고, 이를 역행해야 하는 상황에서 어떻게 대처해야 하는지 파악합니다. 컴포넌트 간의 통신 방식을 묻는 가장 기초적이고 중요한 질문입니다.

문제

부모 컴포넌트에 있는 '장바구니 총액' 데이터를 자식인 '결제창'에 전달하려고 합니다(Props). 그런데 반대로, 자식 컴포넌트에서 쿠폰을 적용해서 부모가 가진 '총액' 데이터를 깎으려면(자식에서 부모로 데이터 전달) 어떤 방식을 사용해야 할까요?

정답 및 풀이

  • 정답: 부모 컴포넌트에서 총액 상태를 변경할 수 있는 '상태 변경 함수(State Updater)'를 만든 뒤, 그 함수 자체를 자식에게 Props로 넘겨주어 자식이 실행하도록 만들어야 합니다.
  • 풀이 과정: 리액트는 데이터가 무조건 위에서 아래로(부모에서 자식으로)만 흐릅니다. 자식이 부모의 데이터를 직접 바꿀 수 있는 권한은 없습니다. 따라서 부모가 리모컨(상태 변경 함수)을 자식에게 빌려주고, 자식은 필요할 때 그 리모컨의 버튼을 눌러 부모의 데이터를 간접적으로 수정하는 방식을 취해야 합니다.

💡 리액트 연계 포인트

이러한 방식을 '상태 끌어올리기(Lifting State Up)'라고 합니다. 여러 자식 컴포넌트가 동일한 데이터를 공유해야 할 때, 공통된 가장 가까운 부모 컴포넌트로 상태를 끌어올려 관리하는 패턴을 매우 자주 사용합니다. 아니면 전역 상태 관리 라이브러리(Zustand, Jotai 등)을 통해 store라는 개념으로 전역 변수를 관리하기도 합니다.


질문 4. 생명주기와 부수 효과 (Lifecycle & Side Effect)

질문 의도

함수형 컴포넌트에서 가장 까다로우면서도 필수적인 훅(Hook)인 useEffect의 동작 원리, 특히 '의존성 배열'의 역할을 정확히 알고 있는지 확인합니다. useEffect를 잘 사용한다면 정말 강력한 최적화 도구가 될 수 있지만, useEffect에서 지켜져야할 조건, 규칙도 많아서 깊이가 있는 문법입니다.

문제

페이지가 처음 열렸을 때 딱 한 번만 환영 모달창을 띄우고 싶어 useEffect를 썼습니다. 이때 두 번째 인자인 의존성 배열(Dependency Array) 자리에 아예 아무것도 적지 않는 것과, 빈 배열을 넣는 것은 어떤 큰 차이를 불러올까요?

정답 및 풀이

  • 정답: 아무것도 적지 않으면 컴포넌트가 렌더링될 때마다 매번 실행되고, 빈 배열을 넣으면 컴포넌트가 화면에 처음 나타날 때(Mount) 딱 한 번만 실행됩니다.
  • 풀이 과정: useEffect는 리액트의 렌더링 과정과 무관하게 외부 시스템(API 호출, 타이머 등)과 동기화하기 위한 '부수 효과'를 처리합니다. 두 번째 인자인 배열은 "이 배열 안의 값이 바뀔 때만 다시 실행해"라는 조건을 의미합니다. 따라서 빈 배열을 주면 관찰할 값이 없으므로 처음 렌더링 후에만 실행되고 다시는 실행되지 않습니다.

💡 리액트 연계 포인트

서버에서 데이터를 초기 로딩할 때 빈 배열을 빼먹으면, 데이터가 들어오면서 상태가 바뀌고, 이로 인해 렌더링이 일어나고, useEffect가 또 실행되어 서버에 다시 데이터를 요청하는 끔찍한 무한 루프를 만들게 됩니다. 의존성 배열 관리는 리액트 성능과 안정성의 핵심입니다.


참고 문헌 (Sources)

본 사전 진단 퀴즈의 기초 개념은 다음의 공식 문서를 참고하여 작성되었습니다.

  • React 공식 문서: React로 사고하기

  • React 공식 문서: State: A Component's Memory

  • React 공식 문서: Synchronizing with Effects