순수 함수 / 순수 컴포넌트
강의 예제에서
add(2,3) -> 항상 5 (순수)
getTime() -> 실행 시점마다 달라짐 (순수 아님)"실행 시점 마다 달라진다 또는 전역 변수를 수정하는 함수는 같은 입력을 넣어도 실행 시점에 따라 결과가 달라지기 때문에 순수하지 않습니다. "라고 하셨고,
이와 마찬가지로 "순수 컴포넌트는
동일한 props와 state가 주어졌을 때 항상 동일한 UI를 반환하는 컴포넌트
(외부 변수를 수정하거나, props를 직접 변경하지 않음)"
라고 했는데
제 머릿속에서는 state는 언제든지 변경될 수 있고 props가 어떤 특정한 state값 ( 서버에서 받아온 상품 목록 리스트)이면 결국 해당 props도 변경 될 수 있다라고 생각이 들어서 좀 많이 자세하게 설명을 듣고 이해 하고, 코드를 작성할 때 적용하기 위해 질문을 올립니다.
추가 ctx)
현재 프론트엔드 개발자입니다. 프론트 개발을 하고 있습니다.
언제나 순수 함수 / 순수 컴포넌트 말로 만 듣고 "이런 거겠지" 라고 하며 어물쩡 넘어갔었는데 요번에 확실하게 개념과 이해 그리고 체화 하고 싶어서 질문 남깁니다.
답변 1
0
안녕하세요 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>;
}위 코드의 ImpureComponent는 label이라는 똑같은 props를 받더라도, 화면을 그릴 때마다 externalCount라는 외부 변수를 읽어오고 심지어 그 값을 증가시킵니다. 따라서 label로 "상품"이라는 동일한 입력을 주어도 렌더링 될 때마다 "상품: 1", "상품: 2", "상품: 3"으로 결과가 계속 달라집니다. 실행 시점마다 달라지는 getTime()과 다를 바가 없기 때문에 순수하지 않은 것입니다. 반면에 우리가 실무에서 지향해야 하는 순수 컴포넌트는 외부 요인을 철저히 배제합니다.JavaScript
function PureComponent({ label, count }) {
return <div>{label}: {count}</div>;
}이 PureComponent는 오직 자신에게 주어진 label과 count라는 props만을 재료로 화면을 그립니다. 외부 세상에 어떤 변수가 있든 전혀 신경 쓰지 않으며, 오로지 넘겨받은 값이 같으면 언제나 같은 UI를 반환합니다. 서버에서 새로운 상품 목록을 받아와서 새로운 state가 형성되고 그 값이 props로 넘어온다면, 컴포넌트는 단지 그 새로운 입력에 맞는 새로운 화면을 정직하게 그려낼 뿐입니다. 이것이 바로 React가 렌더링 결과를 예측 가능하게 만들고, 안심하고 불필요한 렌더링을 최적화할 수 있는 튼튼한 기반이 됩니다.
결론적으로 컴포넌트가 순수하다는 것은 데이터가 변하지 않는 정적인 상태라는 뜻이 아니라, 동일한 재료를 넣었을 때 불순물이 섞이거나 예측 불가능한 결과가 튀어나오지 않는다는 굳건한 약속입니다. 앞으로 실무에서 코드를 작성하실 때, 내가 만든 컴포넌트가 오직 넘겨받은 props와 자신이 가진 state만을 가지고 화면을 결정하고 있는지, 혹시 함수 밖에 있는 무언가를 읽거나 건드리고 있지는 않은지만 스스로 점검해 보신다면 순수 컴포넌트의 개념을 코드에 완벽하게 녹여내실 수 있을 것입니다.
끝으로, 개념을 확실히 체화하고 넘어가시려는 Coi 님의 멋진 학습 태도를 응원하는 마음을 담아 작은 선물을 드리고자 합니다. 현재 저희 우리동네코딩스튜디오 내부적으로 이벤트를 진행하고 있는데요, jeony0535@naver.com 으로 연락 한 통 주시면 우리동네코딩스튜디오 전 강의 쿠폰을 전달해 드리겠습니다. 앞으로도 개발하시면서 궁금한 점이 생기시면 언제든 편하게 질문 남겨주세요.
개인적인 질문인데요..
0
9
1
local3000 쿠키 삭제했는데 인덱스페이지로 이동
0
3
0
라이브 강의 영상 녹화본이 있을까요?
0
14
0
shrimp task manager 사용 관련 질문입니다.
0
11
1
도메인 바꾸는 버튼이 없어요.
0
12
2
title, description 값이 NULL 입니다
0
17
2
인증이 늦었습니다ㅜㅜ 확인부탁드립니다
0
31
1
스웨거 접속이 안되는데 확인 부탁드립니다.
0
26
1
메모리 , rule
0
23
2
클로드 코드로 제작된 앱 검증
0
27
2
자꾸 수정하면 git관련한게 나오네요
0
40
3
만일 실물을 택배로 배송해야 할 경우 주소지 입력하는 방법이 궁금해서요.
1
33
4
초기 세팅에 대해서 정리한 문서가 있을까요?
0
37
2
첫 강의 이후 1년이 지났는데 괜찮을까요.
0
45
2
클로드 코드 실행 방법 문의
0
41
2
설명이 잘못된거같습니다.
1
44
2
안녕하세요 ai툴 질문있습니다.
0
49
2
Python 문의드립니다.
0
39
1
슬랙 연동 방법 및 파일 관련 질문
0
41
2
터미널앱으로 Terminus 사용 문의
0
37
1
스킬생성 후 업데이트.
0
41
2
강의 화면이랑 조금 달라 문의드립니다.
1
42
2
ReactScriptExample 관련 질문
0
47
1
state 객체로 묶기
0
77
1





