목차
지정한 Element를 복사해 반환한다.
부모에서의 props를 자식에게 props를 전달해야하는 경우 사용할 수 있다.
✏️ 사용하려고한 이유
- 부모 컴포넌트 안에 있는 자식 컴포넌트를 외부에서도 볼 수 있게 하기 위해서
- Props 드릴링을 피하기 위해서
- Page > (Container or Manager) > (Component or SearchForm) 구조를 사용하기 위해서
📌 자주 사용한 컴포넌트 구조
const App = () => {
return (
<Page>
<Manager>
<SearchForm />
</Manager>
<Container>
<Component />
</Container>
</Page>
)
}
- Page Component: 모든 API Request를 요청하는 역할을 한다.
- Manager Component : children component에게 Action 함수를 전달하거나 데이터를 가공하여 전달한다. ( 하위 컴포넌트로 SearchForm이 올 경우 사용한다. )
- 처리해야할 Action 함수가 없거나 간단하다면 사용하지 않았다.
- Container Component: children component에게 Action 함수를 전달하거나 데이터를 가공하여 전달한다. ( 하위 컴포넌트로 Table이 올 경우 사용한다. )
- 처리해야할 Action 함수가 없거나 간단하다면 사용하지 않았다.
- Component: UI를 담당한다.
- SearchForm Component: 검색 폼이나 폼을 사용하는 UI를 담당한다.
✏️ 사용법
Page
props 드릴링을 안하고 Child에게 바로 전달 할 수 있고, 외부에서도 볼 수 있다.
/**
* @page
*/
const Page = () => {
const apiResponse = 'apiResponse'
return (
<Parent>
<Child response={apiResponse} />
</Parent>
)
}
Parent
import React, { cloneElement, Fragment, JSXElementConstructor, ReactElement } from 'react'
interface ParentProps {
children: ReactElement<{ data: string; count: number }, string | JSXElementConstructor<any>>
}
/**
* @container
*/
const Parent = ({ children }: ParentProps) => {
return <Fragment>{cloneElement(children, { data: 'data', count: 1 })}</Fragment>
}
Child
중요포인트: 전달받는 props에 undefined도 올 수 있음을 정의해야한다.
interface ChildProps {
data?: string
count?: number
response: string
}
/**
* @component
*/
const Child = ({ data, count, response }: ChildProps) => {
return (
<Box>
{data}
<Box>{count}</Box>
<Box>{response}</Box>
</Box>
)
}
✏️ 주의사항 두 가지
1. 전달받는 props에 undefined도 올 수 있음을 정의해야한다.
Child Component가 단독으로 쓰이면, props를 받을 것이 없기 때문이다.
// Props를 전달 받을 수도 있음!!
<Parent>
<Child />
</Parent>
// Props를 전달 받을 수가 없음!!
<Child />
2. props로 undefined를 전달 받을 수 없다면 사용할 수 없다.
따라서 전달 받는 컴포넌트의 해당 props에 옵셔널 체이닝 연산자를 사용해야한다.
만약 2번을 회피하려면 다른 방법을 사용할 수 있다. 단 의도에 맞게 사용해야한다.
✏️ 다른 방법
page
/**
* @page
*/
const Page = () => {
const apiResponse = 'apiResponse'
return <Parent>{(props) => <Child response={apiResponse} {...props} />}</Parent>
}
Parent
import { ReactNode } from 'react'
interface ParentProps {
children: (props: { data: string; count: number }) => ReactNode
}
/**
* @container
*/
const Parent = ({ children }: ParentProps) => {
return <Fragment>{children({ data: 'data', count: 1 })}</Fragment>
}
Child
interface ChildProps {
data: string
count: number
response: string
}
/**
* @component
*/
const Child = ({ data, count, response }: ChildProps) => {
return (
<Box>
{data}
<Box>{count}</Box>
<Box>{response}</Box>
</Box>
)
}
✏️ 두 방법의 공통점
부모에서의 props를 children에게 props를 전달해야하는 경우 사용할 수 있다.
✏️ 두 방법의 차이점
두 번째 방법은 props를 수정하거나 변경할 수 없다. 즉 복제하지 않는다.
첫 번째 방법은 props를 수정하거나 변경할 수 있다. 즉 얕은 복제를 한다.
'Language > React' 카테고리의 다른 글
React 브라우저 전체 화면 모드 (0) | 2023.07.05 |
---|---|
React 메모이제이션 실험 (0) | 2023.06.28 |
React 라이브러리 없이 캐러셀 구현하기 (0) | 2022.11.28 |
React svg를 컴포넌트로 사용하기 (0) | 2022.11.27 |
React AWS Amplify DataStore Tutorial (0) | 2022.10.10 |