-
동일한 패턴이 여러 컴포넌트에서 쓰이고 있다면? - React 고차 컴포넌트로 해결하기!FrontEnd/React 2023. 1. 1. 23:05반응형
고차 컴포넌트란?
"고차 컴포넌트는 컴포넌트를 가져와 새 컴포넌트를 반환하는 함수이다."라고 공식 홈페이지에서 정의하고 있다.
규모가 큰 애플리케이션에서 DataSouce에 접근하여 SetState를 호출하는 동일한 패턴이 반복적으로 발생할 때 유용하다.
class CommentList extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { // "DataSource" 는 글로벌 데이터 소스입니다. comments: DataSource.getComments() }; } componentDidMount() { // 변화감지를 위해 리스너를 추가합니다. DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { // 리스너를 제거합니다. DataSource.removeChangeListener(this.handleChange); } handleChange() { // 데이터 소스가 변경될때 마다 comments를 업데이트합니다. this.setState({ comments: DataSource.getComments() }); } render() { return ( <div> {this.state.comments.map((comment) => ( <Comment comment={comment} key={comment.id} /> ))} </div> ); } } //-------------------------------- class BlogPost extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { blogPost: DataSource.getBlogPost(props.id) }; } componentDidMount() { DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ blogPost: DataSource.getBlogPost(this.props.id) }); } render() { return <TextBlock text={this.state.blogPost} />; } }
위 두 컴포넌트는 DataSouce에 접근하여 DataSource.getBlogPost, DataSource.getComments를 이용해
State를 설정한다.하는 일은 다르지만 비슷한 패턴으로 작성되었으므로 이를 위한 추상화가 필요하다.
const CommentListWithSubscription = withSubscription( CommentList, (DataSource) => DataSource.getComments() ); const BlogPostWithSubscription = withSubscription( BlogPost, (DataSource, props) => DataSource.getBlogPost(props.id) );
이런식으로 withSubscription이라는 일반함수를 통해 두 컴포넌트를 구성했다.
/ 이 함수는 컴포넌트를 매개변수로 받고.. function withSubscription(WrappedComponent, selectData) { // ...다른 컴포넌트를 반환하는데... return class extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = { data: selectData(DataSource, props) }; } componentDidMount() { // ... 구독을 담당하고... DataSource.addChangeListener(this.handleChange); } componentWillUnmount() { DataSource.removeChangeListener(this.handleChange); } handleChange() { this.setState({ data: selectData(DataSource, this.props) }); } render() { // ... 래핑된 컴포넌트를 새로운 데이터로 랜더링 합니다! // 컴포넌트에 추가로 props를 내려주는 것에 주목하세요. return <WrappedComponent data={this.state.data} {...this.props} />; } }; }
withSubscription함수는 래핕된 컴포넌트를 새로운 데이터로 렌더링하는 것이 특징이다!
래핑된 컴포넌트는 새로운 props, data와 함께 컨테이너의 모든 props를 전달받고, 이 데이터는 출력에 사용됩니다.
이런식으로 코드의 재사용성을 높일 수 있습니다.
자세한 내용은 공식홈페이지를 참고하세요!
https://ko.reactjs.org/docs/higher-order-components.html
고차 컴포넌트 – React
A JavaScript library for building user interfaces
ko.reactjs.org
반응형'FrontEnd > React' 카테고리의 다른 글
JSX 기본 내용 정리 (0) 2023.02.07 React 비용 계산하기 - React Profiler API (1) 2023.01.08 React 성능을 최적화 해보자! (0) 2023.01.02 로딩중입니다...는 React로 어떻게 사용할까? (1) 2022.12.27 부모에서 자식까지 일일이 Prop전달하기 싫을 때? (0) 2022.10.02