React에서는 컴포넌트 단독으로도 사용이 가능하지만 다른 컴포넌트를 감싸는 wrapper 컴포넌트로도 사용이 가능하다.
// 1. 컴포넌트 단독으로 사용
<LoadingSpinner />
// 2. wrapper 컴포넌트로 사용
<Layout>
<SortingButton sort={sort} onClick={handleQuotes} />
<AddForm onAddQuote={onAddQuote} />
</Layout>
wrapper 컴포넌트로 사용할 경우에는 해당 컴포넌트 내에 작성된 요소들은 children이라는 props로 컴포넌트에 전달된다.
wrapper 컴포넌트에서는 반드시 이 children을 리턴하는 마크업에 포함시켜야 화면에 노출된다.
const Layout = ({ children }) => {
return <main className={styles.main}>{children}</main>;
};
만약 wrapper 컴포넌트를 사용하는 부모 컴포넌트가 아닌 wrapper 컴포넌트에서 전달받은 children에 추가적인 props를 더 전달하고자 할 때는 어떻게 하면 될까?
react의 cloneElement 함수를 이용하여 children 컴포넌트를 복사한 후, cloneElement의 두 번째 인자로 넘겨주고 싶은 props를 함께 전달하여 사용하면 된다.
const Layout = ({ children }) => {
const childrenWithProps = Children.map(children, (child) => {
if (isValidElement(child)) {
return cloneElement(child, { 추가할_PROPS_이름: 'PROPS_값' });
}
return child;
});
return <div className={classes.card}>{childrenWithProps}</div>;
};
export default Layout;
주의할 점으로는 아래 예시처럼 컴포넌트를 div, ul 등의 별도의 태그로 감싸서 사용하는 경우에는 해당 태그에 props가 전달되므로 주의해야 한다.
// Layout에서 children에 props를 주입하면 SortingButton, QuoteItem이 아닌 Link(a), ul에 전달됨
<Layout>
<Link to={`?sort=${sorts[sort]}`}>
<SortingButton sort={sort} onClick={handleQuotes} />
</Link>
<ul className={classes.list}>
{sortedQuotes?.map((quote) => (
<QuoteItem key={quote.id} id={quote.id} author={quote.author} text={quote.text} />
))}
</ul>
</Layout>
참고 자료
'Frontend > React' 카테고리의 다른 글
React.js - 드래그 앤 드롭 파일 업로드 만들기 (2) | 2023.07.31 |
---|---|
React.js - contenteditable 사용시 발생하는 오류 해결 (0) | 2023.06.08 |
React.js - useEffect vs useLayoutEffect 차이점 알아보기 (2) | 2022.04.24 |
react-router-dom 버전 5 vs 6 비교 및 차이점 알아보기 (2) | 2022.04.19 |
Redux Toolkit - A non-serializable value was detected in an action, in the path: `type` 오류 해결 (2) | 2022.04.01 |