Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions 13장-리액트 안티패턴 원칙 돌아보기/박선화.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# 13장 리액트 안티패턴 원칙 돌아보기

## 일반적인 안티페턴 돌아보기

#### Props Drilling

Prop Drilling은 prop이 더 깊은 계층의 컴포넌트에 쓰이기 위해 여러 컴포넌트 계층을 통과
할 때 나타나며, 이 prop을 직접 사용하지 않고 전달만 하는 중간 컴포넌트들의 불필요하게 렌
더링을 유발합니다. 이는 복잡하고 유지하기 어려운 코드로 이어질 수 있습니다.

- 해결책 : Context API를 사용하여 중앙 저장소를 만들고 이에 접근하는 기능을 사용하면, 컴포넌트 트
리가 Prop Drilling 없이 필요할 때 prop에 액세스할 수 있습니다.

#### 긴 prop 목록과 너무 많은 기능을 가진 컴포넌트

긴 prop 목록과 많은 양의 로직을 품고 있는 거대한 컴포넌트는 이해하기 쉽지 않고 재사용과 유지보수가 어려운 괴물이 될 수 있습니다. 이 안티패턴은 컴포넌트 또는 모듈은 변경해야 할 이유가 하나만 있어야 한다는 단일 책임 원칙(SRP)을 위반합니다.

- 해결책 : 컴포넌트를 더 작고 다루기 쉬운 컴포넌트로 나누고 관심사를 분리하면 이 문제를 개선할 수 있습니다. 각 컴포넌트는 명확한 단 하나의 책임을 구현해야 합니다. 사용자 정의 훅 또한 컴포넌트 코드를 단순하게 하고 크기를 줄이는 강력한 수단입니 다.

#### 비즈니스 로직 누수

비즈니스 로직 누수는 순수한 렌더링만 담당해야 할 컴포넌트에 비즈니스 로직이 추가될 때 발생합니다. 이는 애플리케이션 관리를 복잡하게 만들고 컴포넌트 재사용 가능성을 낮춥니다.

- 해결책 : 사용자 정의 혹을 사용하여 프레젠테이션 로직에서 비즈니스 로직을 분리하거나, 비즈니스 로직을 별도의 모듈 또는 계층으로 재배치하면 이 문제를 해결할 수 있습니다. 또한 ACL을 적용하는 방법도 효과적 입니 다.

#### 뷰 영역의 복잡한 로직

뷰 컴포넌트 내에 복잡한 로직을 삽입하면 코드가 뒤죽박죽되면서 이해하기 어렵고 유지보수가 힘들어집니다. 뷰는 가능한 한 깔끔하게 유지되어야 하며, 오직 데이터 렌더링에 대한 책임만 있어야 합니다.

- 해결책 : 복잡한 로직을 사용자 정의 훅, 유틸리티 기능 또는 별도의 비즈니스 로직 계층으로 재배치하면 뷰 컴포넌트를 깔끔하고 관리하기 쉽게 유지할 수 있습니다. 일단 컴포넌트를 더 작게 분해한 다음, 점차 로직을 적절한 곳으로 분리하는 것이 좋습니다.

#### 단계별 테스트 부족

애플리케이션 기능을 확인하기 위한 적절한 단위, 통합, E2E 테스트가 없다면. 버그 발생으로 이어지고 리팩터링과 확장이 어려운 코드가 될 수 있습니다.

- 해결책 : TDD와 함께 단위, 통합, E2E 테스트를 포함하는 강력한 테스팅 전략을 적용하면 코드 정확도가 높아지며 유지보수가 쉬워집니다.

#### 13.1.6 중복된 코드

애플리케이션의 여러 컴포넌트 또는 영역에 걸쳐 유사한 코드가 반복되면 코드베이스 유지보수가 복잡해지고 버그 발생 가능성이 높아집니다.

- 해결책 : 중복 배제 원칙 (DRY)을 준수하고 공통의 기능을 유틸리티 함수, 컴포넌트 또는 훅으로 추상화하여 공유하면 코드 중복을 줄이고 유지보수성을 높일 수 있습니다. 일반적인 안티패턴을 세세하게 살펴보았으니. 이제 이를 해결하기 위해 설계 원칙을 탐구하는 단계로 넘어갑니다. 설계 원칙은 해결책을 제공할 뿐만 아니라 더 깔끔하고 효율적인 코드를 작성하도록 안내합니다.

## 디자인 패턴 훑어보기

리액트에는 안티패턴에 대응하는 효과적인 패턴이 있으며, 흥미롭게도 이러한 패턴 중 일부는 리액트 컨텍스트를 넘어 더 다양한 시나리오에서 유용합니다. 이러한 패턴들을 빠르게 다시 살펴봅시다.

#### 고차컴포넌트

고차 컴포넌트(HOC)는 컴포넌트 로직을 재사용하기 위한 유용한 패턴입니다. HOC는 컴포넌트를 전달받고 추가 속성 또는 동작이 추가된 새로운 컴포넌트를 반환하는 함수입니다. HOC를 활용하면 컴포넌트 간에 공통된 동작을 추출하고 공유할 수 있으며. Prop Drilling 및 코드 중복과 같은 문제를 완화하는 데 도움이 됩니다.

#### render prop

render prop 패턴은 값이 함수인 prop을 사용하여 리액트 컴포넌트 간에 코드를 공유하는 기술입니다. 이는 함수를 컴포넌트에 prop으로 전달하는 방법이며, 그 함수는 리액트 요소를 반환합니다. 이 패턴은 재사용과 합성을 적극 활용함으로써 긴 prop 목록과 거대해지는 컴포넌트와 같은 문제를 해결합니다.

#### 헤드리스 컴포넌트

헤드리스 컴포넌트는 동작과 로직을 관리하지만 ui를 렌더 링하지 않는 컴포넌트로, 사용자에게 렌더링에 대한 제어권을 넘깁니다. 동작 로직을 프레젠테이션 로직에서 분리하며, 비즈니스 로직 누수 및 복잡한 뷰 로직에 대한 해결책이 될 수 있습니다. 이를 통해 컴포넌트를 더욱 유연하고 유지보수가 가능하게 만듭니다.

#### 데이터 모델링

데이터 모델링은 데이터를 구성하고 정의하는 것을 수반하며, 애플리케이션 내의 데이터를 이해하고 관리하는 데 도움이 되므로 이를 통해 컴포넌트 내의 로직을 단순화할 수 있습니다. 이 원칙은 뷰의 복잡한 로직과 비즈니스 로직 누수를 해결하는 데 사용될 수 있습니다.

#### 계층화된 아키텍처

계층화된 아키텍처는 각 계층이 특정 책임을 지게 하도록 관심사를 분리하고 코드를 구성하는 것을 말합니다. 이는 더 체계적이고 관리하기 쉬운 코드베이스로 이어지며, 비즈니스 로직 누수 및 뷰에서의 복잡한 로직과 같은 문제를 해결할 수 있습니다.

#### 인터페이스로서의 컨텍스트

컨텍스트를 인터페이스로 활용하면 컴포넌트가 여러 계층을 거 쳐 prop을 전달할 필요 없이 데이터와 상호작용할 수 있습니다. 이 전략은 Prop Drilling과 prop 목록이 많아지는 문제를 완화하여 컴포넌트 트리를 더 읽기 쉽고 유지보수가 가능하게 만들 수 있습니다.

## 기본 설계 원칙 복습하기

#### 단일 책임 원칙(SRP)

단일 책임 원칙은 클래스 또는 컴포넌트가 변경되어야 할 이유는 단 하나만 있어야 한다는 의미입니다. 단일 책임 원칙을 준수하면 유지보수가 가능하고 이해하기 쉬운 코드로 이어질 수 있으며, 거대한 컴포넌트나 복잡한 로직을 가진 뷰 컴포넌트와 같은 문제를 완화할 수 있습니다.

거대한 컴포넌트를 더 작은 컴포넌트로 나누고, 새로운 훅을 만들며, 날씨 애플리케이션에 ACL (오류 방지 계층)을 추가하는 리팩터링 작업에 이르기까지, 다양한 수준에서 이 원칙을적용하고 살펴보았습니다. 특히 거대한 컴포넌트에 복잡하게 얽힌 로직을 다룰 때. 이 원칙을 가장 우선해서 고려해야 합니다.

#### 의존관계 역전 원칙(DIP)

의존관계 역전 원칙은 구체화가 아닌 추상화에 의존하는 것을 강조합니다. 이를 통해 상위 추상 레벨과 하위 구현 레벨을 분리할 수 있습니다. 이 원칙은 비즈니스 로직 누수를 관리하고 관심사를 분리하는 데에 활용될 수 있습니다.

#### 중복 배제 원칙(DRY)

중복 배제 원칙은 코드 내에서 반복을 최소화하는 것입니다. 이 원칙을 준수함으로써 코드 중복을 최소화하고 코드베이스를 더 쉽게 유지하고 확장할 수 있습니다.

#### ACL(오류 방지 계층)

ACL은 애플리케이션의 여러 영역 또는 계층 간의 장벽 역할을 하며, 안정적인 인터페이스를 만듭니다. ACL의 구현은 비즈니스 로직 누수를 관리하고 관심사를 깔끔하게 분리하기 위한 강력한 전략입니다. ACL은 코드가 다른 시스템과 상호작용해야 할 때 특히 유용합니다. 특히 여러 팀과 협업할 때 흔히 나타납니다. ACL을 통해 명확한 시스템 경계를 설정하면 다른 시스템에서 일어나는 변경의 영향을 줄일 수 있습니다. 애플리케이션을 더 쉽게 제어하고 여러 시스템을 통합하여 운영할 때 생기는 잠재적인 문제를 완화할 수 있습니다.

#### 합성

합성은 다른 컴포넌트를 활용하여 또 다른 컴포넌트를 만들 수 있음을 의미하며, 재사용성과 단순성을 향상시키는 리액트의 핵심 원칙입니다. 합성을 사용하면 긴 prop 목록. 거대한 컴포넌트, 코드 중복 등 다양한 문제를 해결할 수 있습니다. 이는 더욱 유지보수 가능하고 정리된 코드베이스를 만들 수 있게 해줍니다.

지금까지 알아본 안티패턴, 디자인 패턴 및 원칙을 이해하는 것은 프런트엔드 코드베이스의 복잡성을 관리하는 데 매우 중요합니다. 그러나 개발자가 매일매일 업무를 하며 마주하는 실전기술 경험 역시 똑같이 중요합니다.

## 기법과 실무 예제 정리

이 책에서는 테스트와 점진적인 개선의 중요성을 강조하였습니 다. 이 방식은 코드의 품질을 높여줄 뿐만 아니라 비판적 사고 능력, 한 번에 하나씩 문제를 해결하는 데 집중할 수 있는 능력을 키워줍니다.

#### 사용자 승인 테스트

사용자 승인 테스트(UAT)는 애플리케이션이 원하는 사양과 기능에 부합하도록 보장하는 개발 과정의 중추적인 부분입니다. UAT를 구현하면 개발 초기에 문제를 식별하는 데 도움이 될 수 있으며. 애플리케이션이 올바르게 동작하고 있는지 확인할 수 있습니다. 테스트는 사용자의 관점에서 작성되어야 하며 구현 세부 사항보다는 사용자에게 가치를 제공하는 데 중점을 두어야 합니다. 이는 상위 레벨에서 기능을 구현하기 시작할 때 특히 중요합니다.

#### TDD

TDD는 코드보다 테스트를 먼저 작성하는 소프트웨어 엔지니어링 기술입니다. 이는 테스트 코드를 작성한 다음에 실제 코드를 구현하여 먼저 작성한 테스트 코드를 통과시키고 리팩터링을 하는 반복적 개발 주기로 세분화됩니다. 코드베이스 기능이 잘 동작하고 버그가 없는지 확인하는 데에 TDD가 크게 도움이 될 수 있으며. 각 개발 단계에서 테스트 코드의 누락을 방지해 줍니다.

#### 리팩터링과 코드 스멜

리팩터링은 외부 동작을 변경하지 않고 기존 코드의 설계를 개선합니다. 코드 스멜을 인지하고 코드를 지속적으로 리팩터링하면 더 건강하고 유지보수 가능한 코드베이스가 될 수 있습니다. 리팩터링은 코드 중복, 뷰의 복잡한 로직 및 비즈니스 로직 누수와 같은 문제를 해결하는 데 중요한 역할을 합니다.
여기까지 안티패턴과 설계 원칙을 분석하고 여러 가지 기법을 알아봤습니다. 이제 이 책에서 다루지 못했던 리액트, 타입스크립트 및 소프트웨어 설계 원칙에 대한 이해를 더욱 심화시키고 기술을 배울 수 있는 추가 자료를 제공합니다.