Writing React Components
우리는 최신 React(19+)를 사용하며 명확성, 정확성, 유지보수성을 중시하는 모범 사례를 따릅니다.
컴포넌트 구조 및 스타일
- 선호: 작고 집중된 단일 책임을 가진 컴포넌트
- 선호: 화살표 함수보다는 이름이 있는
function컴포넌트- 예외: 익명 콜백, 인라인 렌더 프롭, 클로저
- 선호: 가능한 경우 명시적 반환 타입과 props 타입 지정(TypeScript)
- 컴포넌트를 평평하고 읽기 쉽게 유지하고 깊이 중첩된 JSX 피하기
- 관련 로직을 함께 그룹화(이벤트 핸들러, 파생 값, 도우미 함수)
상태 관리
- 회피:
useEffect()사용- 자세한 내용은 "You Might Not Need An Effect" 가이드를 참조하세요.
- 선호: 상태 동기화 대신 렌더링 중에 값 파생
- TanStack Query(
@tanstack/react-query)를 통해 데이터 가져오기
- 회피: 불필요한
useState()또는useReducer()사용- 가능한 경우 props나 다른 상태에서 상태 파생
- 상태를 가능한 가장 낮은 컴포넌트로 지역화
- 금지: 꼭 필요한 경우가 아니면 props를 상태에 미러링하지 않음
- 제어되지 않은 상태 동기화보다 제어된 컴포넌트 선호
렌더링 및 파생
- 선호: 인라인 또는 도우미 함수를 통해 파생 값 계산
- 성능 문제가 입증된 경우에만
useMemo()를 제한적으로 사용 - 회피: 조기 최적화
- 렌더링 로직을 결정적이고 부작용 없이 유지
이벤트 처리
-
회피: JSX에서 인라인 이벤트 핸들러
-
선호:
function handleClick() { // ... } <button onClick={handleClick} />; -
다음보다:
<button onClick={() => { /* ... */ }} />
-
-
핸들러를 명확하게 이름 지정(
handleSubmit,handleChange,handleClose) -
핸들러를 작게 유지하고 복잡한 로직은 도우미 함수로 추출
효과, 데이터 및 부작용
- 회피: 다음을 위한 효과:
- 파생 상태
- 데이터 변환
- 핸들러에 포함될 수 있는 이벤트 기반 로직
- 부작용이 불가피한 경우 최소화, 격리, 잘 문서화
- 원시 효과보다 프레임워크 수준 또는 외부 추상화(라우터, 데이터 라이브러리) 선호
Props 및 컴포지션
- 선호: 설정보다 컴포지션
- 회피: 과도한 boolean props; 표현적인 API 선호
children을 의도적으로 사용하고 예상 구조 문서화- props 이름을 의미 있고 예측 가능하게 유지
성능 및 안정성
- 선호: 기본이 아닌 필요한 경우에만 안정적인 참조
- 회피: 꼭 필요한 경우가 아니면 불필요한 메모이제이션(
memo,useCallback) - 목록을 렌더링할 때 키를 안정적이고 의미 있게 유지
일반 원칙
- 컴파일러보다 사람을 위해 코드 작성
- 영리함보다 명시성 선호
- 가독성과 장기 유지보수에 최적화
- 패턴이 복잡하다고 느껴지면 컴포넌트 경계를 재고