- Published on
리액트 공식문서 스터디 2-2 주차
- Authors

- Name
- junyeol kim
Rendering Lists
배열을 데이터로 렌더링하기
const people = ['A', 'B', 'C']
const listItems = people.map((person) => <li>{person}</li>)
return <ul>{listItems}</ul>
여러 개의 유사한 컴포넌트를 보여줄 때 데이터 배열을 활용한다.
map()을 사용해 배열 요소들을 컴포넌트로 변환할 수 있다.
배열의 항목들을 필터링하기
const chemists = people.filter((person) => person.profession === 'chemist')
const listItems = chemists.map((person) => <li>{person.name}</li>)
filter()을 이용해 조건(ex: 특정 직업)에 맞는 항목만 추려서 렌더링할 수 있다.
리스트 key의 중요성
keyprop은 각 리스트 아이템을 고유하게 식별하며, 필수다.보통 데이터의 고유 id를 사용한다 (
key={person.id})key는 형제 간에만 고유하면 된다.
key를 가져오는 곳 및 규칙
데이터베이스의 ID, 로컬 UUID 등 신뢰할 수 있고, 변하지 않는 값을 사용한다.
렌더 중 즉석 key 생성은 버그와 성능 저하의 원인이다.
key와 React 생명주기의 연결고리
React 컴포넌트 생명주기란?
Mount: 컴포넌트가 DOM에 처음 추가될 때
Update: props, state 변경으로 리렌더링 될 때
Unmount: 컴포넌트가 DOM에서 사라질 때
리스트 렌더링에서 key의 역할
key가 제대로 설정되면 React는 "이 컴포넌트가 이전에 있던 그 컴포넌트"라는 걸 정확하게 인식할 수 있다.
컴포넌트의 내부 상태(state), 입력값, focus 등 생명주기 전체 흐름이 안전하게 이어진다.
잘못된 key 사용(index, 즉석 생성)은 컴포넌트가 새로 만들어진 것으로 오인하여 state 초기화, focus 문제 등등 버그가 발생할 수 있다.
즉, key는 컴포넌트가 생성, 업데이트, 제거되는 생명주기를 올바르게 관리하는 데 필수적이다.
- 복잡한 동적 리스트/폼에서는 key 때문에 생명주기를 제대로 관리하지 못하면 사용자 경험과 코드의 안정성 모두가 위험해질 수 있다.
Keeping Components Pure
컴포넌트의 순수성(Purity)이란?
순수 함수(Pure Function):
- 외부의 값을 변경하지 않고, 동일한 입력에 대해 항상 동일한 출력을 반환한다.
React의 기본전제:
컴포넌트는 "순수 함수"처럼 동작해야 한다.
똑같은 props, state, context를 전달하면 항상 똑같은 JSX(출력)을 반환해야 한다.
렌더링 중에는 Side Effects를 피해야 한다.
렌더링은 계산만 해야 하며, 변경이나 효과를 일으키면 안된다.
애니메이션 시작, 데이터 fetch, DOM 조작 등과 같은 사이드 이펙트는 이벤트 핸들러, useEffect와 같은 훅에서 렌더 이후에 수행해야 한다.
Strict Mode로 순수성 확인
개발 중
<React.StrictMode>를 사용하면, 컴포넌트의 렌더 함수를 두 번 호출하고 순수하지 않은 컴포넌트는 이상하게 보이거나 예측 불가한 동작을 한다. 그렇기에 오류를 빠르게 잡을 수 있다.또한, 실제 배포에서는 영향이 없다.
지역변수 mutation
함수(컴포넌트) 안에서 초기화한 변수/객체의 변경은 가능하다.
즉, 같은 렌더 동안 만들어진 값 안에서 push, pop 등 사용이 가능하다. 하지만, 함수 밖 (전역, 상위 범위) 변수 변경은 불가능하다.
Understanding Your UI as a Tree
UI와 트리(Tree) 모델의 관계
UI는 여러 요소가 부모와 자식 관계로 중첩(nesting)되는 구조로 만들어질 수 있다.
브라우저의 DOM(HTML), CSSOM, 모바일 화면 등에서 트리 구조가 활용될 수 있다.
React 역시 컴포넌트들을 트리로 표현하며, 각 컴포넌트가 트리의 노드(node)가 될 수 있다.
Render Tree(렌더 트리)
여러 컴포넌트를 중첩(nested)해서 만들면, 자연스럽게 부모와 자식 구조가 생길 수 있다.
React 앱이 렌더될 때 각 컴포넌트 관계가 트리로 표현되어, 렌더 트리가 만들어질 수 있다.
root node는 앱의 루트 컴포넌트(대개
<App />)가 될 수 있다.각 부모가 자식을 렌더하고, 자식은 다시 자신의 자식을 렌더하여, 트리가 완성될 수 있다.
트리의 각 노드는 컴포넌트를 나타낼 수 있다.
렌더 트리에는 HTML 태그가 직접 표시되지 않고, 트리는 오직 React 컴포넌트들로 구성될 수 있다.
Conditional Rendering과 트리 변화
부모 컴포넌트가 props나 state에 따라 자식 컴포넌트를 동적으로 다르게 렌더할 수 있다.
즉, 렌더 트리 구조가 render pass마다 바뀔 수 있다.
다양한 조건에서 트리 구조가 달라질 수 있으므로, 데이터 흐름 및 최적화를 이해하기에 유리할 수 있다.
Top-level vs Leaf Components
Top-level component는 루트에 가까운 상위 컴포넌트로, 하위 컴포넌트 전체 랜더링 성능에 큰 영향을 줄 수 있다.
Leaf component는 트리의 가장 아래에 있는(자식이 없는) 컴포넌트로, 자주 렌더될 수 있다.
이 두 종류를 파악하면 앱의 성능이나 데이터 흐름 분석에 매우 유리할 수 있다.
Module Dependency Tree(의존성 트리)
JS 파일/모듈 간의 import/export 관계 역시 트리 구조로 표현될 수 있다.
각 노드는 모듈이 될 수 있고, 각 브랜치는 import 관계를 나타낼 수 있다.
루트 노드는 앱의 엔트리포인트 파일(보통
index.jsorApp.js)이 될 수 있다.렌더 트리와 다르게, 의존성 트리에는 함수, 상수, 데이터 모듈 등 비컴포넌트도 포함될 수 있다.
어떤 모듈이 어디에 import되어 있고, 어떤 모듈이 꼭 필요한지 파악할 수 있다.
번들러(Webpack 등)는 이 트리를 참고해 필요한 JS만을 번들로 묶어서 배포할 수 있다.