REACT
리엑트는 JS라이브러리이다.
JS로만 운영되며, Node 기반으로 작동된다. 이때문에 리엑트를 사용하기 위해서는 반드시 컴퓨터에 노드가 설치되어 있어야 한다.
노드 준비가 완료되었다면, 다음과 같은 프로젝트 제작절차를 따르면 된다.
- React 프로젝트를 제작하기 위해서는
npx create-react-app .
npm create vite@latest
을 사용한다. - 프로젝트 폴더가 성공적으로 만들어 졌다면,
npm run dev
로 리엑트 서버를 호출 한다. - 서버를 닫고 싶을때는
ctrl + c
2025년 02월 14일 기준, cra템플릿의 지원이 종료되어 vite나 기타 번들 시스템을 통해 프로젝트 제작이 권장된다..
제작된 프로젝트 폴더를 살펴보면, node_modules라는 폴더를 찾을 수 있다. 해당 폴더 안에는 보통 내가 설치한 패키지들이 담겨 있으며, 루트폴더의 package.json의 dependencies에서 모듈이 어느 모듈을 기반으로 동작하는지 등을 확인할 수 있다.
React또한 css를 reset하는 것처럼 리셋해주는 프로세스가 존재한다.
- 루트폴더의 src폴더에 App.test, logo.svg, reportWebVitals.js, setupTest.js를 삭제
- App.js에 logo 관련 코드 줄을 모두 주석처리/삭제한다.
- index.js에서 reportWebVitals관련 코드 줄을 모두 주석처리/삭제한다.
- index.js에서 strictMode 삭제
React 프로젝트를 Git에 업로드할때, node_modules는 용량이 크므로, .gitignore
파일을 만들어서 제외시켜줄 필요가 있다.
프로젝트를 실행시키기 위해서 다시 node_modules를 설치하기 위해서는 npm i
를 통해 dependencies에 해당되는 모든 모듈 파일들을 알아서 다시 설치해준다.
React를 사용해야하는 이유
React는 기존의 양방향 바인딩 방식의 MVC패턴에서 발생한 복잡한 상태관리의 문제점으로 인해 등장한 Flux패턴을 사용한다.
Flux패턴은 데이터 흐름이 단방향이며, 데이터 흐름을 파악하기 쉽고, 데이터 흐름을 통제하기 쉽다는 장점이 있다.
이러한 특성 때문에 소셜, ott 등 서비스를 개발하는 업체들은 이처럼 Flux 패턴을 사용하게 된다. 이러한 Flux 패턴을 사용하는 라이브러리가 바로 React이며, Netflix, 페이스북, 트위터 등 많은 회사들이 React를 사용하고 있다.
React는 SSR(Server-Side-Rendering)방식이 아닌 CSR(Client-Side-Rendering)방식을 사용한다.
기존의 DOM은 서버가 클라이언트에 제공한것에 반해, 가상돔(VDOM)은 해당 돔을 그대로 복제해서 클라이언트에서 관리한다.
이로 인해 이벤트나 작업 등은 가상돔에서 먼저 확인을 하고, 해당 요소만 서버한테 받아와 상당히 효율적으로 작업이 진행되며, 로딩도 안걸리게 되어 속도가 향상된다.
이처럼 새로운 기술스택을 사용할때, 객관적인 시점으로 장단점을 잘 이해하고 기술스택을 왜 사용하는지에 대해 알아보는 습관을 들이자.
Snippets
Emmet기능과 유사하며, VSCode에서 확장설치를 해줘야한다. (ES7 React snippets)
rafc
//React Arrow Function Component
rfc
//React Function Component
Snippet을 사용하게 되면, 기본적으로 React 모듈을 import하며, 함수의 이름은 해당 컴포넌트의 파일명을 따라간다.
Component Life Cycle
React는 컴포넌트 기반의 라이브러리이다. 컴포넌트란, UI를 구성하는 독립적이고 재사용 가능한 코드의 조각을 의미한다. 각 컴포넌트는 자체적인 상태와 생명주기를 가지며, 다른 컴포넌트와 결합하여 복잡한 사용자 인터페이스를 구축할 수 있다.
리엑트의 컴포넌트 생명주기는 다음과 같은 3단계를 따른다.
- 마운트(Mount) - 컴포넌트가 최초로 생성되고 실제 DOM에 삽입되는 과정
- 업데이트(Update) - 컴포넌트의 상태 혹은 props가 변경될때 다시 발생할 수 있다.
- 언마운트(Unmount) - 컴포넌트가 제거되는 과정
마운트와 렌더링을 헷갈리면 안된다. 마운트는 컴포넌트가 최초로 생성되고 실제 DOM에 삽입되는 과정이다. 이때, 컴포넌트의 ui를 계산하고 이를 화면에 그리는 것이 렌더링이다.
마운트는 컴포넌트 생명주기 중 한번만 발생되며, 렌더링은 컴포넌트의 상태 혹은 props가 변경될때 다시 발생할 수 있다.
리렌더링을 유발하는 조건은 3가지가 존재한다.
- 컴포넌트의 상태가 변경될때
- 컴포넌트의 props가 변경될때
- 부모 컴포넌트가 리렌더링될때
리엑트가 비대해짐에 따라, 브라우저에서 컴파일하고 다시 마운트하고 하는 과정이 너무 부담이 커지게 됨.
이에 따라 미리 파일들을 조합하고 컴파일링해주는 번들링 시스템이 생김
babel, modules, webp등 다양한 파일들을 번들링하기 위해, node.js가 등장하게 됐다.
Model이 바뀌면 화면이 다시 렌더링된다.
들어갈 회사의 레거시 코드가 클래스 컴포넌트기반이어도 피하지 말자. 어차피 ai가 이러한 폼펙팅을 해결해준다.
Styling
REACT에서 스타일을 먹이기 위해서는 기존처럼 CSS를 사용하거나, REACT용 SCSS를 사용할 수 있다.
허나 이들보다는 앞으로 Style Component를 더 많이 사용하게 된다.
이말고도 인라인 스타일시트를 부여할 수도 있다. 허나, 기존의 인라인 방식과 다르게, 스타일을 반드시 객체의 형태로 부여해야한다. 이는 JSX문법때문이다.
<div style={{backgroundColor: "red"}}>
또한 예시에서 알 수 있듯이, 모든 속성은 카멜표기법을 따르게 된다.
Event
기존의 js와는 다르게, 반드시 onHandler로 이벤트를 부여한다. (REACT에서는 EventListener를 거의 안쓴다.)
on핸들러를 사용함으로써, JSX의 문법 특성상 절대로 출력부에는 “문”이 들어올 수 없으므로, 함수를 리펙토링하는것이 거의 필수화된다.
Event 함수 사용시 주의사항
반드시 콜백으로 사용해야함 (REACT는 Virtual DOM을 사용하기 때문)
Event가 발생될때, on핸들러에 부여한 함수는 반드시 콜백함수의 형태로 실행되어야 한다. 따로 리펙토링을 시켜서 콜백을 만들어주거나, 아니면 실행할 함수 내용을 반드시 콜백으로 호출해야한다.
이는 REACT가 VDOM을 사용하기 때문이다. VDOM은 기존에 있던 DOM을 그대로 복제해서 가져오는 건데, 브라우저가 마운트가 됐을때 바로 실행되는 함수의 특성 때문에 일반 DOM에서도 해당 함수가 바로 실행되게 된다.
허나 일반 DOM에서는 함수에 대한 데이터가 전무하므로 기능을 수행하지 못하는 함수는 계속 무한루프에 빠지게 된다. 이 때문에 우리는 콜백함수를 사용하여 큐(Queue)의 자료구조를 띠는 CallStack에 넣어서 마운트되자 함수가 실행되는것을 막아줘야한다.
이러한 VDOM의 특성 때문에 리엑트에서는 콘솔도 100% 신뢰할 수 없다.
하지만 브라우저가 즉시 마운트 될때 api와 같이 외부에서 데이터를 불러올 때는 바로 실행되어야하므로 콜백이 아니라 바로 함수를 부여해야한다.
가상돔을 사용하는 점 때문에 REACT에서는 EventListener뿐만 아니라 QuerySelector도 사용을 안하며, 대부분의 상태변화는 useState, useRef와 같은 Hook들을 통해 관리한다.
구조
React 프로젝트를 시작할 때, 컴포넌트 및 데이터들에 관한 구조를 상세하게 기획해둔 상태에서 코드 작업을 진행해둔 상태에서 코드 작업을 진행해야한다.
React에서도 Vanilla JS와 마찬가지로, 컴포넌트를 제작할 때 다음과 같이 목업을 만들어두고, 컴포넌트가 어느 위치에 들어갈지 대략적인 위치를 잡아준다.
function App() {
return (
<div className="App">
<div>Header</div>
<div>Todo Editor</div>
<div>Todo List</div>
</div>
);
}
최적화
컴포넌트의 불필요한 리렌더링을 최소화하여 성능을 향상 시키고 컴퓨터의 메모리 사용을 효율적으로 관리하는 작업.
React는 컴포넌트를 기반으로 만들어짐으로 인해, 마운트 - 렌더링 - 언마운트의 생애주기를 반드시 거치게 된다. 이 과정에서 상태 변화나, 부모 컴포넌트의 리렌더링 등으로 인해 자식 컴포넌트가 불필요하게 다시 렌더링 될 수 있다. 이러한 불필요한 리렌더링은 성능 저하를 초래할 수 있으며, 이를 최소화 하기 위한 최적화 작업이 필요하다.
-
최적화 작업은 웹앱 제작 및 기능 구현을 해놓고 진행해야하며, 모든 기능을 최적화할 필요까진 없다. 최적화를 할 때 구조를 뒤엎어야할 정도의 상황이 발생하면 최적화를 포기하는 것이 차라리 이롭다.
횡단 관심사(Cross Cutting Concern)
컴포넌트들을 횡으로 나열해 뒀을때, 교차/겹쳐지는(Cross) 렌더링.
메인기능 역할을 담당하는 메인 컴포넌트들은 종단(세로)로 배치 되고, 여기저기에서 사용되는 공통 컴포넌트(헤더, 푸터)들은 횡단(가로)로 배치된다. 즉, 공통컴포넌트는 횡단 관심사의 요소로, 고차컴포넌트화를 통해 횡단관심사에서 요소를 빼내는 최적화 작업이 필요하다. 고차컴포넌트화에 대한 내용은 React.memo()
에서 더 자세히 확인할 수 있다.
메모이제이션(Memoization)
이전에 작성된 값을 메모리에 저장하여 동일한 입력이 다시 주어졌을 때 재계산하지 않고 저장된 결과를 재사용하는 최적화 기법.
메모를 작성할때, 한번 적어두면 해당 메모를 직접 수정하지 않는 이상 값의 변화가 일어나지 않고 계속 남아있는 것을 응용한 최적화 기법.
메모이제이션(최적화)을 위한 React Hook 함수 3인방: useMemo
, React.memo()
, useCallback
기타 최적화 방법
최적화작업을 하는 방법은 훅 함수들 말고도 다양하다. useEffect를 통해 의존성배열로 최적화작업을 한다거나, useReducer 등등 최적화 할 수 있는 방법은 상당히 다양하다. 여기서 알아야할 부분은 상단에 설명해둔 최적화 훅 함수 3인방은 오직 최적화를 위해서 나온 함수들이며, 역할이 분명하기 때문에 Semantic하게 그들을 사용하는 것이다.