Hard skills
이번 편에서는 전 편에서 다룬 useState() 함수를 조금 더 살펴봅니다.
useState란?
React의 useState() 함수는 함수 컴포넌트에서 지역 상태(local state)를 생성하고 관리하기 위한 리액트 훅(Hook)입니다. 컴포넌트가 다시 렌더링되어도 상태를 기억하고 유지할 수 있게 해주는 핵심 기능입니다.초반에 우리가 만든 Subscription 컴포넌트 코드를 꺼내 보겠습니다.
두 번째 줄에 useState() 함수가 보이죠? 함수 컴포넌트는 JavaScript 언어 관점에선 함수입니다. 함수는 호출하면 내부 변수들이 생성되지만 함수가 종료되면 모두 사라집니다. 즉 상태가 유지되지 않지요. useState() 함수는 함수 내부라는 지역(local)에 상태를 생성하고 관리하는 기능을 제공합니다.
컴포넌트와 지역성
React는 컴포넌트 기반 모델을 채택하고 있습니다. 컴포넌트는 지역적으로 상태를 관리하는 게 중요한데, 그래야 컴포넌트가 격리되어 재사용하기 용이하기 때문입니다. 컴포넌트에서 상태란 이전 편에서 버튼을 예시로 다뤘지요. 이러한 지역성은 다음과 같은 이점을 제공합니다.
- 컴포넌트 간의 독립성 보장
- 코드의 재사용성 향상
- 테스트와 디버깅 용이성
- 상태 관리의 단순화
이런 컴포넌트가 마치 함수같지 않나요? 컴포넌트는 마치 순수(pure) 함수처럼 동작합니다. 순수 함수가 안 되더라도 적어도 멱등성을 갖습니다. 상태가 변하지 않는 한 몇 번을 호출해도 결과가 동일하지요.
상태 변경하기
useState() 함수를 호출하면 두 개 객체를 배열에 담아 반환합니다. 이 함수의 인자는 상태값의 초기값을 설정합니다. useState() 함수가 반환하는 배열의 첫 번째 객체는 상태 객체로 값을 갖습니다. 두 번째 객체는 상태 값 변경 함수입니다. 첫 번째 객체를 직접 변경해서는 안 됩니다.
이는 React의 단방향 데이터 흐름을 유지하고, 리렌더링이 오작동하는 것을 방지합니다.
베일아웃(Bailout)
베일아웃은 React의 성능 최적화 기능 중 하나로, 새로운 상태가 이전 상태와 동일할 경우 불필요한 리렌더링을 방지합니다.
참조 타입 다루기
베일아웃은 간혹 입문자를 혼란에 빠뜨리는데, 배열이나 객체처럼 참조 타입을 상태 값으로 다룰 때 혼란에 빠뜨리곤 합니다.
JavaScript는 배열과 객체를 값으로 다루지 않고 참조해서 다룹니다.
이 이미지는 참조로 대상을 전달해 다루는 것과 값으로써 대상을 전달해 다루는 것을 표현하는 유명한 이미지입니다. 왼쪽은 참조로 전달하는 것으로, 컵이라는 객체를 직접 전달하는 게 아니라 컵에 연결된 개체를 전달한 것입니다. 따라서 참조 대상인 컵에 커피를 따르자 원본 컵에도 커피가 차오릅니다. 둘은 실질적으로 동일한 객체이기 때문이지요. 하지만 값으로 전달하는 오른쪽 이미지는 컵이 그 자체로 전달됐으므로(복사) 전달된 컵에 커피를 따라도 원본 컵엔 아무런 일도 벌어지지 않습니다. 컵 두 개가 된 것이니까요.
Python 등 몇 몇 언어와 마찬가지로 JavaScript도 배열이나 객체 등 일부 자료형(타입)을 참조 타입(자료형)으로 다룹니다.
이 코드에서 member 객체는 컨테이너로써 객체이며 내부 내용인 member.name을 수정해도 컨테이너 그 자체인 member 객체는 동일하게 유지됩니다. 컨테이너 내용물만 바뀐 것이지요.
그래서 이와 같이 {과 } 표현식으로 새 객체를 생성해야 비로소 member와 member2가 서로 다른 객체가 됩니다. 또는,
이와 같이 전개 구문(Spread syntax, Spread operator)을 사용해 보다 간편하게 새 객체를 만들기도 합니다.
함수로 상태 변경하기
여태까지 객체 변경 함수(예 : setEmail())로 상태값을 변경할 때 변경할 새 값을 인자로 전달했습니다.
상태 값을 변경하는 또 다른 방법은 함수를 인자로 전달하는 것입니다.
이전 편에서 다룬 리액트의 상태 관리 동작의 특성으로 기인하는 몇 몇 상황에서 이러한 방법이 필요합니다.
최신 상태 값 보장
리액트는 내부적으로 비동기로 렌더링과 상태 관리를 합니다. 따라서 setCount(count + 10)을 호출하는 시점에 count 상태값이 몇 인지 확언하기 어렵습니다. 1에다 1을 더해 2인 상태에서 count + 10을 실행해 12가 될 것이라 예상하지만 11이 되는 경우도 발생할 수 있습니다.
그에 반해 함수로 상태 값을 변경하면 리액트는 count의 값이 최신 상태 값이라는 걸 보장합니다.
연속된 상태 갱신 처리
이 역시 비동기 처리와 관련된 경우입니다.
이 코드의 경우 첫 번째 갱신이 이뤄지지 않은 count 상태 값을 사용하게 됩니다. count 초기 값이 1이라면, 첫 번째 상태 값 변경으로 count는 2, 두 번째 상태 값 변경으로 count는 3이 되길 기대하지만, 첫 번째 상태값이 반영되기 전에 두 번째 상태 값 변경을 실행하는 경우 최종 count는 3이 아닌 2가 되는 거지요.
푸딩캠프 이야기
협업 환경 설문 조사
여러분에겐 사수가 있으신가요? 토이 프로젝트는 성공리에 출시하셨나요? 다른 사람은 이 질문에 어떻게 답변할까요? 사수가 있는지, 성공리에 출시해서 출시하여 운영해본 경험은 있는지.
현재 푸딩캠프에서 이에 대한 설문조사를 하고 있습니다. 현재까지 설문조사에 응답한 내용에 따르면 사수가 없는 환경에서 일하는 주니어 개발자가 상당히 많습니다. 여러분의 환경은 어떠한가요? 여러분의 참여를 기다립니다.
참여하신 분께는 추첨을 통해 IT 도서를 증정하며, 여러분이 참여할수록 현 실태에 대해 함께 알아갈 수 있습니다.
커피챗 이야기
푸딩캠프 커피챗은 현재 한날과 콴 코치 두 명이 여러분을 기다리고 있습니다. 연말이라 그런 걸까요? 한날 코치는 갑작스레 예약 신청이 몰리면서 12월까지 대부분 예약이 완료되었고, 이제 막 커피챗을 시작한 콴 코치님에게도 슬슬 예약이 차기 시작합니다.
콴 코치님의 경우 PM/PO 직군에 대한 멘토링, 코칭, 컨설팅을 진행하시는데, 커피챗을 마친 분들의 만족도가 높습니다. 이 뉴스레터를 구독하시는 여러분이, 또는 주변에 고민이 많은 PM/PO 직군의 동료가 있다면 콴 코치님의 커피챗을 신청해보세요!
토이스토리 특강 : Front-end Testing
푸딩캠프에서 토이스토리 프로그램 참가자를 대상으로 하는 특강, 3회는 프론트엔드 테스팅입니다. 테스트 코드를 작성하며 달력을 만들며, 이번엔 실습을 병행합니다. 😇
테스트에 대한 개괄은 지난 2회, 백엔드 테스팅에서 다루어서 이번엔 간단히 몇 가지만 설명하고, 바로 실습하는 자리지요. 프론트엔드 테스팅에 관심 있으신 분은 꼭 들어보세요!
- 2024년 12월 3일 화요일, 20시 30분
- 주제 : 테스트 코드 작성하며 달력 만들기
- 예상 시간 : 2~3시간
- 실습 : React, Vitest, Vite 기반. (다음 주 중 Boilerplate 제공)
- 참가 대상 :
- 토이스토리 참여자 (지난 특강 피드백 제출자에 한 함)
- 푸딩캠프 뉴스레터 구독자
댓글
의견을 남겨주세요