inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

React 마스터 클래스: Part 1 - 미션으로 깨우치는 렌더링 본질과 설계

18. 순수 컴포넌트 — 예측 가능한 React 코드를 만드는 핵심 원칙

순수 함수 / 순수 컴포넌트

해결된 질문

23

Coi

작성한 질문수 11

0

강의 예제에서

add(2,3) -> 항상 5 (순수) 

getTime() -> 실행 시점마다 달라짐 (순수 아님)

"실행 시점 마다 달라진다 또는 전역 변수를 수정하는 함수는 같은 입력을 넣어도 실행 시점에 따라 결과가 달라지기 때문에 순수하지 않습니다. "라고 하셨고,

이와 마찬가지로 "순수 컴포넌트는

동일한 props와 state가 주어졌을 때 항상 동일한 UI를 반환하는 컴포넌트

(외부 변수를 수정하거나, props를 직접 변경하지 않음)"

라고 했는데

제 머릿속에서는 state는 언제든지 변경될 수 있고 props가 어떤 특정한 state값 ( 서버에서 받아온 상품 목록 리스트)이면 결국 해당 props도 변경 될 수 있다라고 생각이 들어서 좀 많이 자세하게 설명을 듣고 이해 하고, 코드를 작성할 때 적용하기 위해 질문을 올립니다.


추가 ctx)

현재 프론트엔드 개발자입니다. 프론트 개발을 하고 있습니다.

언제나 순수 함수 / 순수 컴포넌트 말로 만 듣고 "이런 거겠지" 라고 하며 어물쩡 넘어갔었는데 요번에 확실하게 개념과 이해 그리고 체화 하고 싶어서 질문 남깁니다.



HTML/CSS javascript react 웹앱 frontend

답변 1

0

nhcodingstudio

안녕하세요 Coi 님, 프론트엔드 개발을 하시면서 순수 함수와 순수 컴포넌트 개념을 단순히 넘기지 않고 완벽하게 체화하고자 깊게 고민하시고 이렇게 질문을 남겨주셔서 진심으로 감사합니다.

강의 예제에서 언급했던 add(2, 3)이 항상 5를 반환하여 순수하고, getTime()은 실행할 때마다 결과가 달라져서 순수하지 않다는 개념을 먼저 떠올려 보시면 좋습니다. 질문해주신 내용을 보면 state는 언제든 변할 수 있고 서버에서 받아오는 상품 목록 같은 props도 결국 계속 바뀔 텐데 어떻게 항상 동일한 UI를 반환한다고 하는 건지 혼란스러우신 점을 아주 정확하게 짚어주셨습니다. 처음에 이 개념을 접할 때 누구나 한 번쯤 겪게 되는 아주 자연스럽고 핵심적인 의문입니다.

우리가 짚고 넘어가야 할 가장 중요한 오해는 항상 동일한 UI를 반환한다는 말이 애플리케이션이 실행되는 내내 데이터나 화면이 영원히 변하지 않는다는 뜻이 결코 아니라는 점입니다. 여기서 말하는 순수성의 핵심은 시간이 아니라 특정 시점에 주어지는 특정 입력값에 대한 이야기입니다. 즉, 컴포넌트라는 함수에 입력으로 들어온 props와 state 값이 정확히 똑같다면 오늘 화면을 그리든 내일 그리든, 혹은 백 번을 다시 그리든 그 결과물인 UI는 토시 하나 틀리지 않고 똑같아야 한다는 뜻입니다.

이 부분을 현실의 자판기에 비유해서 설명해 보겠습니다. 완벽하게 순수한 자판기가 있다고 가정해 보겠습니다. 이 자판기에 500원이라는 동전(props)과 콜라 버튼을 누르는 행위(state)가 입력되면 이 기계는 항상 콜라(UI)를 내어줍니다. 만약 내일 이 자판기에 1000원을 넣고 사이다 버튼을 누른다면 당연히 사이다가 나오겠지만, 그렇다고 해서 이 자판기가 순수하지 않은 기계가 되는 것은 아닙니다. 단지 입력값이 달라졌으니 그에 맞게 결과가 달라진 것뿐입니다.

반면 순수하지 않은 자판기는 500원과 콜라 버튼을 똑같이 입력했는데도, 자판기 내부 온도가 높다는 외부 요인 때문에 갑자기 미지근한 물을 내어주거나, 자판기 관리자가 몰래 세팅을 바꿔두어 랜덤한 음료수를 내어주는 식입니다. 똑같은 입력을 주었는데도 외부 상황이나 시간에 따라 결과가 요동치는 것이죠.

React의 컴포넌트도 이 자판기와 완벽하게 똑같이 동작해야 합니다. 컴포넌트는 결국 자바스크립트 함수이고, 렌더링은 그 함수를 실행하는 행위입니다. React는 state가 변경되거나 서버에서 새로운 props를 받아오면 컴포넌트라는 함수를 다시 호출하여 새로운 재료들을 던져줍니다. 이때 컴포넌트는 오직 자신이 방금 건네받은 그 재료들만을 사용해서 화면을 그려내야 합니다. 함수 밖에 있는 전역 변수를 몰래 가져와서 화면을 그리거나, 건네받은 props 자체를 컴포넌트 안에서 마음대로 수정해버리면 동일한 재료를 줬을 때 동일한 결과가 나온다는 보장을 할 수 없게 됩니다.

이를 코드로 직접 비교해보면 훨씬 직관적으로 다가오실 것입니다. 먼저 외부 변수에 의존해서 순수성을 잃어버린 컴포넌트를 살펴보겠습니다.

let externalCount = 0;

function ImpureComponent({ label }) {
  externalCount += 1;
  return <div>{label}: {externalCount}</div>;
}

위 코드의 ImpureComponentlabel이라는 똑같은 props를 받더라도, 화면을 그릴 때마다 externalCount라는 외부 변수를 읽어오고 심지어 그 값을 증가시킵니다. 따라서 label로 "상품"이라는 동일한 입력을 주어도 렌더링 될 때마다 "상품: 1", "상품: 2", "상품: 3"으로 결과가 계속 달라집니다. 실행 시점마다 달라지는 getTime()과 다를 바가 없기 때문에 순수하지 않은 것입니다. 반면에 우리가 실무에서 지향해야 하는 순수 컴포넌트는 외부 요인을 철저히 배제합니다.JavaScript

function PureComponent({ label, count }) {
  return <div>{label}: {count}</div>;
}

PureComponent는 오직 자신에게 주어진 labelcount라는 props만을 재료로 화면을 그립니다. 외부 세상에 어떤 변수가 있든 전혀 신경 쓰지 않으며, 오로지 넘겨받은 값이 같으면 언제나 같은 UI를 반환합니다. 서버에서 새로운 상품 목록을 받아와서 새로운 state가 형성되고 그 값이 props로 넘어온다면, 컴포넌트는 단지 그 새로운 입력에 맞는 새로운 화면을 정직하게 그려낼 뿐입니다. 이것이 바로 React가 렌더링 결과를 예측 가능하게 만들고, 안심하고 불필요한 렌더링을 최적화할 수 있는 튼튼한 기반이 됩니다.

결론적으로 컴포넌트가 순수하다는 것은 데이터가 변하지 않는 정적인 상태라는 뜻이 아니라, 동일한 재료를 넣었을 때 불순물이 섞이거나 예측 불가능한 결과가 튀어나오지 않는다는 굳건한 약속입니다. 앞으로 실무에서 코드를 작성하실 때, 내가 만든 컴포넌트가 오직 넘겨받은 props와 자신이 가진 state만을 가지고 화면을 결정하고 있는지, 혹시 함수 밖에 있는 무언가를 읽거나 건드리고 있지는 않은지만 스스로 점검해 보신다면 순수 컴포넌트의 개념을 코드에 완벽하게 녹여내실 수 있을 것입니다.

끝으로, 개념을 확실히 체화하고 넘어가시려는 Coi 님의 멋진 학습 태도를 응원하는 마음을 담아 작은 선물을 드리고자 합니다. 현재 저희 우리동네코딩스튜디오 내부적으로 이벤트를 진행하고 있는데요, jeony0535@naver.com 으로 연락 한 통 주시면 우리동네코딩스튜디오 전 강의 쿠폰을 전달해 드리겠습니다. 앞으로도 개발하시면서 궁금한 점이 생기시면 언제든 편하게 질문 남겨주세요.

슬라이드 오타

0

4

0

git 설치

0

14

1

강의 소스 코드는 어디서 볼수 있나여?

1

14

1

전체적인 개발에 대해 문의드립니다.

1

23

1

자료집 관련

0

11

2

13. (App 2) 기본기 훈련 에서

0

16

1

챌린지 시작일 문의

0

19

0

17강 강의에 목데이터 첨부파일이 없습니다.

2

23

2

2. 어떤 도구를 사용하는 것이 가장 유리할까? 강의 중

0

17

1

링크 관리 기능 구현 실패

0

15

1

줄바꿈 시 \ 필수인가요?

0

25

2

11차시 Antigravity IDE 설치 후

0

19

1

2605 이후 최신 클로드코드 강의 추가 부탁드립니다.

0

22

2

처음 에이전트 설정을 잘못 했을 경우 수정 하는 방법

0

16

1

5,6,7,8 내용이 없어요

0

18

1

커리큘럼 문서 제공받을 수 있을까요?

0

23

1

ThemeProvider를 이용해서 NextThemeProvider를 따로 생성하여 Layout.tsx에 적용하는 이유는 뭘까요?

0

15

1

mission 09-01 을 수행할 수 없어요

0

25

1

문제점

0

22

2

outputStyle 설정하는데 어디서 문제일까요?

0

28

3

test.txt파일 삭제시 rm명령어이니 클로드의 질문이 있어야 한다고 하셨는데

0

21

2

검은화면

0

30

3

ReactScriptExample 관련 질문

0

44

1

state 객체로 묶기

0

70

1