-
[React] React의 Component와 StateReactJS 2023. 11. 23. 04:06
React의 Component
리액트의 강력한 특징은 무엇일까? 리액트 공식 문서의 가장 메인에 나온 특징은 다음과 같다.
가장 먼저는 선언적이라는 것이다. 데이터가 변경될 시 적절한 컴포넌트만 효율적으로 갱신하고 렌더링한다는 것이다. 두번째로는 컴포넌트 기반이라는 것이다. 스스로 상태를 관리하는 간단한 형태의 캡슐화된 컴포넌트를 만들고, 이러한 컴포넌트들을 조합하여 복잡한 UI를 만드는 것이다. 즉 한꺼번에 복잡한 UI를 만드는 것이 아닌, 단순한 형태의 컴포넌트들로 쪼개 관리하는 것이다.
그렇다면 이렇게 컴포넌트들을 쪼개는데 어떠한 기준이 있을까? 다음과 같은 몇 가지 기준을 참고하면 좋을 듯하다.
- SRP (Single Responsibility Principle) : 단일 책임 원칙이란 모든 클래스는 하나의 책임만 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 일컫는다. 즉 리액트에서는 하나의 컴포넌트가 너무 커지고 있다면, 하나의 기능 및 상태를 책임지는 컴포넌트들로 분리해야 한다는 것이다. 하나의 컴포넌트가 변경되어야하면, 하나의 이유여야한다.
- CSS : CSS에서 우리가 이미 사용하고 있는 클래스를 활용하여 이를 기점으로 컴포넌트를 나누는 것도 생각해 볼 만하다.
- Design’s Layer : 디자이너가 구상한 구조를 기점으로 나누는 것도 좋다. 특히 디자이너가 붙인 이름을 팀원들이 자주 사용한다면 편리할 것이다.
- Information Architecture : JSON Schema(JSON 데이터의 형식을 기술한 문서)의 영향을 받는다는 의미이다. 백엔드 서버에서 넘겨주는 JSON 데이터의 구조가 어떤 식으로 넘겨주는지에 따라 컴포넌트를 나누는 기준이 많이 달라지기 때문이다. 실제로 많이 쓰게 되고 자연스러운 SRP를 위해서 사실상 강제된다. JSON 객체 속 동일한 구조를 반복적으로 보여주는 과정에서 자연스럽게 SRP를 생각하게 되고 컴포넌트를 분리하게 된다. ex) 카테고리 별 데이터 전달 시 카테고리를 기준으로 컴포넌트 분리
Atomic Design
아토믹 디자인은 UI를 물질의 가장 작은 단위인 원자(atom)처럼 최대한 쪼개고, 그것들을 조합하고 점진적으로 확장시켜 일관성 있는 디자인 시스템을 구축하는 것을 목표로 한다. 아토믹 디자인의 구성 요소로는 원자(atom)에서 시작해, 분자(molecule), 유기체(organism), 템플릿(template), 페이지(page)가 있다.
Extract Function
아주 흔히 쓰이는 SRP를 위한 수단이다. 변화의 크기(영향 범위)를 제약한다. 일단 길게 코드를 작성하고, 적절히 자를 수 있는 부분이 보일 때 “함수로 추출”한다. 또는 코드를 작성하기 어려운 상황에 직면했을 때 함수로 추출한다. 바로 다른 파일을 만들어야 한다고 생각하지 않아도 된다. 컴포넌트 나누는 기준이 애매하면 다시 하나의 컴포넌트로 합쳤다가(Inline Method) 다시 나눠줘도 됨.
Props
나눠진 컴포넌트를 서로 연결하는 방법이다. 자바스크립트를 쓰면 props를 넘겨줄 때, 하나의 객체로 묶어서 props를 넘겨주면, 안에 뭐가 들었는지 모르기 때문에 하나씩 넘겨줘야 하는데, 타입스크립트를 쓰면, type이나 interface로 잘 정의가 되어있기 때문에 한꺼번에 객체로 넘겨줄 수 있어서 사용에 용이하고, 재사용시에도 용이하다. 이러한 이유로 props는 TypeScript를 잘 쓰거나 잘못 쓰게 되는 포인트 중 하나로 적절한 균형점을 잡는 게 중요하다. 테스트 코드를 작성하면 재사용성을 평가하기 쉬워진다.
React의 State
React의 state는 “변경”을 다루기 위한 요소이다. 대략적으로 이야기하면, 어떤 컴포넌트의 state가 바뀌면 해당 컴포넌트와 하위 컴포넌트를 다시 렌더링하게 된다. 아무렇게나 막 만들어도 되지만, 일관성과 효율을 위해 DRY 원칙을 따르는 SSOT를 만든다.
- DRY (Don’t Repeat Yourself) : 중복 배제
- SSOT (Single Source of Truth) : 단일 진실 공급원
즉 하나의 데이터에 대해서 props로 자식 컴포넌트들에게 넘겨주는 과정에서 불필요하게 state를 만들 필요는 없다. 상위 컴포넌트의 state가 변경되면 알아서 하위 컴포넌트들의 값들이 재렌더링된다. 또한 불필요하게 넘겨받는 데이터들을 state로 만들면 중복으로 state를 갖게 되어 단일한 데이터의 공급원이 아니게 되므로 실제 데이터가 변경되었을 때 바뀌지 않는 등 혼란을 빚게 된다.
React State의 조건:
- 변경돼야 한다. 변경되지 않는 건 state로 다룰 가치가 없다.
- 부모 컴포넌트가 props를 통해 전달한다면 state가 아니다
- 다른 state나 props를 이용해 계산 가능하다면 state가 아니다.
다루는 상태가 너무 많으면 복잡할 수 있다. TypeScript를 잘 쓰면 직접 관리하는 props로 넘겨줄 시 type 또는 interface로 잘 정의한다면, 하나의 객체로 넘겨주어 보여지는 상태의 수를 줄여줄 수 있다. 그렇다면 그 상태를 누가 관리해야 할까? 더 정확히는, 상태를 누가 소유해야 할까? (React만 쓴다면) 해당 상태에 의존적인 컴포넌트를 모두 포함하는 상위 컴포넌트가 상태를 소유해야 한다.
Lifting State Up
해당 컴포넌트의 상태에 의존적인 컴포넌트를 모두 포함하는 상위 컴포넌트가 상태를 소유해야 하므로 상위 컴포넌트까지 state 끌어올리기 작업을 해야한다. 그 후 state와 setState를 props로 해당 하위 컴포넌트까지 내려주어야 한다.
Inverse Data Flow
하위 컴포넌트의 props로 setState나 handleChange와 같은 함수를 전달한다. 흔히 콜백 함수라고 부른다. TypeScript(정확히는 JavaScript)는 함수가 일급(first-class) 객체다. 즉, 어떤 함수를 다른 함수에 인자로 넘겨주거나, 어떤 함수를 리턴값으로 사용할 수 있다. 익명 함수, 클로저 등과 함께 사용하면 시너지가 크다고 한다.
- 일급 함수 : 프로그래밍 언어는 해당 언어의 함수들이 다른 변수처럼 다루어질 때 일급 함수를 가진다고 한다. 예를 들어, 일급 함수를 가진 언어에서 함수는 다른 함수들에 전달 인자로 제공되고, 다른 함수에 의해 반환될 수 있으며, 변수에 값으로서 할당될 수 있다.
- 일급 객체 : 다른 객체들에 일반적으로 적용 가능한 연산을 차별점 없이 모두 지원하는 객체를 가리킨다. JavaScript에서 함수는 다른 함수로 전달되거나 반환받을 수 있고, 변수와 속성을 할당받을 수도 있기 때문에 일급 객체에 해당한다. 일급 객체의 조건은 다음과 같다.
- 변수에 할당(assignment)할 수 있다.
- 다른 함수를 인자(argument)로 전달 받는다.
- 다른 함수의 결과로서 리턴될 수 있다.
'ReactJS' 카테고리의 다른 글
[React] React Testing Library (0) 2023.11.30 [React] TDD (0) 2023.11.29 [React] REST API와 GraphQL (4) 2023.11.22 [React] VDOM(Virtual DOM)이란? (2) 2023.11.20 [React] 리액트에서 JSX를 쓰는 이유(feat. 리액트 공식문서) (2) 2023.11.19