Learn React / Components
신현호
React Docs
목차
Components
#Fragment
#Fragment
는 래퍼 노드 없이 엘리먼트를 그룹화할 수 있습니다.
jsx
<>
<OneChild />
<AnotherChild />
</>
Fragment로 엘리먼트를 그룹화하면 DOM 엘리먼트와 같은 다른 컨테이너로 엘리먼트를 감싸는 경우와 달리 레이아웃이나 스타일에 영향을 주지 않습니다.
다른 엘리먼트와 마찬가지로 Fragment를 변수에 할당하고 props로 전달하는 등의 작업도 가능합니다.
jsx
function CloseDialog() {
const buttons = (
<>
<OKButton />
<CancelButton />
</>
)
return (
<AlertDialog buttons={buttons}>
Are you sure you want to leave this page?
</AlertDialog>
)
}
<></>
문법 대신에 명시적으로 Fragment를 작성해야 하는 상황이 있습니다. 바로 반복을 통해 여러 엘리멘트를 렌더링할 때 입니다.
이 때는 key
속성을 제공하기 위해 일반 JSX 문법을 사용해야 합니다.
jsx
function Blog() {
return posts.map((post) => (
<Fragment key={post.id}>
<PostTitle title={post.title} />
<PostBody body={post.body} />
</Fragment>
))
}
Profiler
#Profiler
는 프로그래밍 방식으로 React 트리의 렌더링 성능을 측정할 수 있습니다.
jsx
<Profiler id="App" onRender={onRender}>
<App />
</Profiler>
이런식으로 컴포넌트 트리를 Profiler로 감싸주게 되면 렌더링 성능을 측정할 수 있습니다.
여러 개를 사용하여 애플리케이션을 부분별로 측정할 수 있습니다.
jsx
<App>
<Profiler id="Sidebar" onRender={onRender}>
<Sidebar />
</Profiler>
<Profiler id="Content" onRender={onRender}>
<Content />
</Profiler>
</App>
Profiler를 여러개 중첩 사용 할 수도 있습니다.
jsx
<App>
<Profiler id="Sidebar" onRender={onRender}>
<Sidebar />
</Profiler>
<Profiler id="Content" onRender={onRender}>
<Content>
<Profiler id="Editor" onRender={onRender}>
<Editor />
</Profiler>
<Preview />
</Content>
</Profiler>
</App>
StrictMode
#StrictMode
는 개발 중에 컴포넌트에서 일반적인 버그를 빠르게 찾을 수 있도록 합니다.
jsx
<StrictMode>
<App />
</StrictMode>
Strict Mode는 다음과 같은 개발 전용 동작을 활성화합니다.
- 순수하지 않은 렌더링으로 인해 발생하는 버그를 찾기 위해 컴포넌트가 추가로 다시 렌더링됩니다.
- Effect 클린업이 누락되어 발생하는 버그를 찾기 위해 컴포넌트가 추가로 Effect를 다시 실행합니다.
- 더 이상 사용되지 않는 API의 사용여부를 확인하기 위해 컴포넌트를 검사합니다.
전체 앱에 대한 Strict Mode를 활성화하고싶다면 루트 컴포넌트를 Strict Mode로 래핑하세요.
jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
const root = createRoot(document.getElementById('root'))
root.render(
<StrictMode>
<App />
</StrictMode>
)
Strict Mode 검사는 개발 환경에서만 실행됩니다. 이는 코드에 존재하지만 프로덕션에서 제대로 재현하기 어려울 수 있는 버그를 찾는 데 도움이 됩니다.
Suspense
#Suspense
는 자식 요소가 로드되기 전까지 화면에 대체 UI를 보여줍니다.
jsx
<Suspense fallback={<Loading />}>
<SomeComponent />
</Suspense>
Suspense
는 다음과 같이 사용할 수 있습니다.
콘텐츠가 로드되는 동안 대체 UI 보여주기
애플리케이션의 모든 곳을 Suspense 경계로 감쌀 수 있습니다.
아래 코드에서 React는 Albums
가 로딩될 때 까지 loading fallback
을 보여줍니다. 그리고 로딩이 완료되면 Albums
를 표시합니다.
Suspense
가 가능한 데이터만이 Suspense
컴포넌트를 활성화합니다.
독단적인 프레임워크를 사용하지 않는 Suspense가 가능한 데이터 불러오기 기능은 아직 지원되지 않습니다.
- Relay, NextJS와 같이 Suspense가 가능한 프레임워크를 사용한 데이터 가져오기
lazy
를 활용한 지연 로딩 컴포넌트use
를 사용해서 Promise 값 읽기
Suspense
는 Effect 또는 이벤트 핸들러 내부에서 가져오는 데이터를 감지하지 않습니다.
콘텐츠를 한꺼번에 함께 보여주기
기본적으로 Suspense 내부의 전체 트리는 하나의 단위로 취급됩니다. 예를 들어, 이러한 구성 요소 중 하나라도 어떤 데이터에 의해 지연되더라도 모든 구성 요소가 함께 로딩 표시로 대체됩니다.
jsx
<Suspense fallback={<Loading />}>
<Biography />
<Panel>
<Albums />
</Panel>
</Suspense>
추가적으로, 데이터를 로드하는 컴포넌트가 Suspense의 직접적인 자식일 필요는 없습니다.
jsx
;<Suspense fallback={<Loading />}>
<Details artistId={artist.id} />
</Suspense>
function Details({ artistId }) {
return (
<>
<Biography artistId={artistId} />
<Panel>
<Albums artistId={artistId} />
</Panel>
</>
)
}
중첩된 콘텐츠가 로드될 때 보여 주기
컴포넌트가 일시 중단되면 가장 가까운 상위 Suspense 컴포넌트가 Fallback을 보여줍니다. 이를 통해 여러 Suspense 컴포넌트를 중첩하여 로딩 순서를 만들 수 있습니다. 각 Suspense의 Fallback은 다음 레벨의 콘텐츠를 사용할 수 있게 되면 채워집니다. 예를 들어 앨범 목록에 자체 Fallback을 지정할 수 있습니다.
jsx
<Suspense fallback={<BigSpinner />}>
<Biography />
<Suspense fallback={<AlbumsGlimmer />}>
<Panel>
<Albums />
</Panel>
</Suspense>
</Suspense>
이 변경을 통해 Biography
를 보여줄 때 Albums
의 로딩을 기다리지 않아도 됩니다.
새 콘텐츠가 로드되는 동안 이전 콘텐츠 보여주기
useDeferredValue
의 예시처럼 Suspense
를 통해서도 새 콘텐츠가 로드되는 동안 이전 콘텐츠를 보여줄 수 있습니다.
이미 보인 콘텐츠가 숨겨지지 않도록 방지하기
컴포넌트가 지연되면 가장 가까운 상위 Suspense가 Fallback을 보여주도록 전환합니다. 이미 일부 콘텐츠가 보이는 경우 사용자 경험이 끊길 수 있습니다. 아래 예제를 확인해봅시다.
버튼을 눌렀을 때 ArtistPage
내부의 컴포넌트가 지연되어 가장 가까운 Suspense가 Fallback을 보여주기 시작합니다. 가장 가까운 Suspense는 root 근처이기때문에 전체 사이트 레이아웃이 대체됩니다.
이를 방지하기 위해서 useTransition
의 startTransition
을 사용하여 이 업데이트를 transition
으로 처리할 수 있습니다. 이는 state 전환이 급하지 않으며 이미 공개된 콘텐츠를 숨기기보단 이전 페이지를 계속 표시하는게 좋다는 것을 React에게 알립니다.
위에 예제에서는 이를 적용하여 버튼을 클릭하면 Biography
가 로드될 때까지 대기합니다.
추가적으로, key
를 사용하면 React에서는 서로 다른 컴포넌트로 취급하여 탐색하는동안 Suspense를 재설정하도록 할 수 있습니다.
jsx
<ProfilePage key={queryParams.id} />
신현호
Frontend Developer
프론트엔드 개발자를 꿈꾸고 있는 대학생입니다. 끊임없이 배우고 성장하는 개발자가 되기 위해 노력하고 있습니다.
React Docs
총 5개의 포스트가 존재합니다.