React는 컴포넌트로 사용자 인터페이스를 만드는 자바스크립트 라이브러리입니다. 현재 데이터에 맞게 화면이 어떻게 보여야 하는지 설명하면, 데이터가 바뀔 때 React가 페이지를 그에 맞게 업데이트합니다. React, React JS, ReactJS는 모두 같은 것으로, Facebook(현재 Meta)에서 만든 오픈 소스 라이브러리입니다.
두 버튼을 모두 클릭해 보세요. 각 Counter는 자기만의 숫자를 유지합니다. 각각이 자기 상태를 가진 별도의 컴포넌트 복사본이기 때문입니다. 세 번째 줄 <Counter label="Plums" />를 추가하면 독립적인 새 카운터가 나타납니다.
이 짧은 예제에 React의 바탕이 되는 세 가지 개념이 이미 들어 있습니다. 컴포넌트(Counter와 App은 UI를 반환하는 함수입니다), JSX(return 안의 HTML 같은 문법), 그리고 상태(count, 바뀌면 React가 컴포넌트를 다시 그리게 만드는 값)입니다.
React가 해결하는 문제
사용자 인터페이스는 어떤 데이터를 그린 그림입니다. 데이터가 바뀌면 그림도 바뀌어야 하고, 그 데이터에 의존하는 화면의 모든 부분이 함께 바뀌어야 합니다. 라이브러리 없이는 이 코드를 직접 작성합니다. 각 요소를 찾아서 텍스트, 클래스, 표시 여부를 직접 설정하는 식입니다. 기능이 하나 늘 때마다 업데이트를 잊지 말아야 할 곳도 하나씩 늘어납니다.
React는 이 방식을 뒤집습니다. 주어진 상태에서 화면이 어떠해야 하는지 말하는 함수를 하나 작성하면, 페이지의 어느 부분을 바꿔야 할지는 React가 알아냅니다. 이것을 선언형 UI라고 하며, DOM 변경을 단계별로 나열하는 명령형 코드와 대비됩니다. 한 예제에서 두 방식을 나란히 보겠습니다.
ByHand는 자기 문단을 일반 DOM 코드에 맡깁니다(이펙트는 React가 문단을 만든 뒤에야 그 코드를 실행합니다). 숫자를 변수에 보관하고, querySelector로 각 요소를 찾아 텍스트를 직접 설정합니다. Declarative는 "카운트를 보여 주고, 짝수인지 보여 줘"라고 말할 뿐입니다. handleClick에서 .parity를 설정하는 줄을 지우고 몇 번 클릭해 보세요. 첫 번째 줄은 이제 3이 짝수라고 주장하지만, 두 번째 줄은 렌더링할 때마다 count에서 텍스트를 계산하기 때문에 어긋날 수 없습니다.
React가 페이지를 업데이트하는 방식
상태가 바뀌면 React는 컴포넌트 함수를 다시 호출합니다. 이 호출이 렌더링입니다. 함수는 UI에 대한 새로운 설명을 반환하고, React는 그것을 이전 설명과 비교한 뒤 실제 페이지에서 달라진 부분만 바꿉니다. 메모리 안의 이 설명을 흔히 가상 DOM이라고 부릅니다.
미리보기 아래의 콘솔을 열고 글자를 몇 개 입력해 보세요. 키를 누를 때마다 새 값으로 렌더링 한 번이 기록됩니다. React가 페이지 전체가 아니라 문단의 텍스트와 입력창의 값만 건드렸기 때문에, 입력창은 포커스와 커서 위치를 유지합니다. 렌더링 페이지에서 컴포넌트가 언제 다시 렌더링되는지 정확히 설명합니다.
컴포넌트, JSX, 상태 한눈에 보기
컴포넌트는 이름이 대문자로 시작하는 자바스크립트 함수입니다. 화면에 나타날 내용을 반환하며, HTML 태그처럼 <Counter />로 사용합니다. 페이지는 버튼 같은 작은 컴포넌트부터 설정 화면 전체 같은 큰 컴포넌트까지 이어진 컴포넌트 트리입니다. 컴포넌트를 참고하세요.
JSX는 자바스크립트 안에 마크업을 작성하게 해 주는 문법입니다. 중괄호 안은 다시 자바스크립트이므로 {count}는 값을 보여 주고 {items.map(...)}은 배열을 목록으로 바꿉니다. 브라우저가 실행하기 전에 빌드 도구가 JSX를 일반 함수 호출로 컴파일합니다.
상태는 컴포넌트가 렌더링 사이에 기억하는 데이터입니다. useState 훅으로 만들고, setter를 호출하는 것이 무언가 바뀌었다고 React에 알리는 방법입니다. 데이터는 컴포넌트의 인자인 props를 통해 부모에서 자식으로 흐릅니다.
이 예제는 이 모두를 사용합니다. 상태에 있는 배열로 렌더링한 목록과, 그 목록에 항목을 추가하는 폼입니다.
할 일을 추가하면 두 가지가 동시에 바뀝니다. 목록과 그 아래의 개수입니다. 개수를 업데이트하라고 지시한 적은 없습니다. 둘 다 tasks를 읽기 때문에 둘 다 그 값을 따라갑니다. 시작 배열을 []로 바꾸면 목록 대신 "Nothing to do."가 표시됩니다.
React가 아닌 것
React는 완전한 프레임워크가 아니라 라이브러리입니다. 컴포넌트, 상태, 그리고 그것을 UI로 바꾸는 일을 담당하며, 완성된 앱에 필요한 몇 가지는 의도적으로 빼 두었습니다.
- 라우팅. URL을 페이지에 연결하는 기능이 내장되어 있지 않습니다. React Router와 프레임워크의 라우터가 이 빈자리를 채웁니다.
- 데이터 가져오기와 서버 렌더링. React는 이펙트와 Suspense 같은 도구를 제공하지만, 데이터를 어디서 가져올지, 페이지를 서버에서 어떻게 렌더링할지에 대한 방침은 없습니다.
- 빌드 설정. 브라우저는 JSX를 이해하지 못하므로 Vite 같은 도구로 컴파일해야 합니다.
프레임워크는 React 위에서 이 부분들을 제공합니다. Next.js와 React Router의 프레임워크 모드는 라우팅, 서버 렌더링, 데이터 로딩을 더하며, React 팀은 완전한 앱을 이 중 하나로 시작하도록 권장합니다. 클라이언트 사이드 앱이나 학습용으로는 Vite와 일반 React가 작고 빠른 출발점입니다. React 설치 방법을 참고하세요.
React와 React Native
React 자체는 컴포넌트와 그것이 어떻게 바뀌는지만 설명합니다. 별도의 렌더러가 그것을 눈에 보이는 것으로 바꿉니다. React DOM은 웹 페이지에 렌더링하며, 이 사이트의 모든 예제가 이것을 사용합니다. React Native는 같은 종류의 컴포넌트를 네이티브 iOS와 Android 뷰로 렌더링합니다. 그래서 <div>와 <p> 대신 <View>와 <Text>를 쓰고, HTML이나 CSS 파일이 없습니다. 컴포넌트, props, 상태, 훅은 두 환경에서 똑같이 동작하므로 여기서 배운 내용을 그대로 가져갈 수 있습니다.
React는 언제 배워야 할까
React의 모든 것은 자바스크립트이므로 자바스크립트 기초를 익힌 뒤에 배우세요. 시작하기 전에 다음 내용에 익숙해야 합니다.
- 변수, 함수, 화살표 함수
- 배열과
map,filter메서드 - 객체, 구조 분해, 전개 문법(
...) import와export- 데이터를 불러오기 위한 프로미스와
async/await
이런 내용이 익숙하다면 JSX와 컴포넌트부터 시작하고, 그다음 props와 상태로 넘어가세요. 이펙트, ref, 컨텍스트, 성능 도구는 작은 상호작용 컴포넌트를 만드는 일이 자연스러워진 다음에 배워도 됩니다.
자주 묻는 질문
React는 어디에 사용하나요?
React는 웹 앱, 대시보드, 폼, 싱글 페이지 앱, 일반 웹사이트의 일부처럼 상호작용하는 사용자 인터페이스를 만드는 데 사용합니다. React Native를 쓰면 같은 컴포넌트 모델로 iOS와 Android 앱을 만들 수 있습니다.
React는 프레임워크인가요, 라이브러리인가요?
React는 라이브러리입니다. 컴포넌트, 상태, 렌더링을 담당하지만 라우터, 데이터 가져오기 계층, 빌드 설정은 내장되어 있지 않습니다. Next.js나 React Router의 프레임워크 모드 같은 프레임워크가 React 위에 이런 기능을 더합니다.
React JS와 React는 같은 것인가요?
네. React, React JS, ReactJS는 같은 라이브러리를 부르는 세 가지 이름입니다. "JS"가 붙는 이유는 React가 자바스크립트로, 자바스크립트를 위해 작성되었기 때문입니다.
React를 배우기 전에 자바스크립트를 알아야 하나요?
네. React 컴포넌트는 자바스크립트 함수이므로 함수, 배열(map, filter), 객체, 구조 분해, 화살표 함수, 모듈, 프로미스에 먼저 익숙해져야 합니다.
React와 React Native의 차이는 무엇인가요?
React는 UI를 컴포넌트로 설명합니다. React DOM은 그 컴포넌트를 웹 페이지에 렌더링하고, React Native는 네이티브 모바일 뷰로 렌더링합니다. 컴포넌트, props, 상태, 훅은 두 환경에서 똑같이 동작합니다.