반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- frontend
- DI
- nuxtjs/composition-api buildModules
- vue store
- TCP/IP
- HTTP란
- Spock Mock
- docker desktop 대체
- @Transaction isolation
- 트랜잭션 격리
- Javascript
- mock stub
- Mock vs Stub
- Spock Mock Stub Spy
- 공짜로 Docker Desktop같은거 쓰기
- @Transaction propagation
- mock stub spy
- Docker Desktop 쓰고싶다
- TypeScript
- webpack
- docker desktop 유료화 정책
- ECMAScript
- 의존성주입
- 자바스크립트
- Rancher Desktop설치
- Vue+Typescript
- Spock Stub
- enum
- Spock Spy
- 타입스크립트
Archives
- Today
- Total
끄적끄적
[REACT] Presentational 컴포넌트와 Container 컴포넌트 본문
반응형
프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트
리액트를 이용해 개발을 하고 계신 분들이라면 대부분 이미 알고 계실껍니다.
이번 글을 통해 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트의 개념에 대해 정리해보고자 합니다.
프레젠테이션 컴포넌트
1. 직접적으로 보여지는 부분에 대해 담당한다.
2. Store에 의존적이지 않다.
3. props를 통해 데이터와 callback을 전달 받는다.
4. 마크업과 스타일을 가진다.
5. 데이터를 직접적으로 변경하지 않는다.
6. UI 상태값 이외에 대체로 다른 상태값을 가지고 있지 않는다.
컨테이너 컴포넌트
1. 데이터 핸들링에 대한 위주로 개발한다.
2. 마크업이나 스타일을 가지지 않는다.
3. 리덕스의 액션이나 상태 변경에 대한 로직을 담고 있고, 프레젠테이셔널 컴포넌트에 해당 상태를 전달하거나 함수를 제공한다.
4. 다른 프레젠테이셔널 컴포넌트나 컨테이너 컴포넌트를 관리한다.
이렇게 각자의 용도가 명확하게 정리되어 분리하고, 대규모 프로젝트에서의 리소스 관리를 조금 더 수월하게 해줍니다.
데이터의 공급자와 뷰의 공급자를 나누어 상태나 비지니스로직에 대한 디펜던시를 제거해 주어 유지보수에 대해 편의를 제공합니다.
쉽게 말하면 UI와 DATA핸들링 부분에 대한 분리로 재사용성을 높여주는 겁니다.
예제
- 프레젠테이셔널 컴포넌트
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from 'antd';
const defaultProps = {
number: -1,
onPlus: createWarning('onPlus'),
onSubtract: createWarning('onSubtract')
};
const propTypes = {
number: PropTypes.number,
onPlus: PropTypes.func,
onSubtract: PropTypes.func
};
function createWarning(funcName) {
return () => console.warn(funcName + ' is not defined');
}
const Counter = (props) => {
return (
<div>
<h1>{ props.number }</h1>
<Button type="primary" onClick={ props.onPlus }>+</Button>
<Button type="primary" onClick={ props.onSubtract }>-</Button>
</div>
);
}
Counter.propTypes = propTypes;
Counter.defaultProps = defaultProps;
export default Counter;
- 컨테이너 컴포넌트
import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
// UI Components
import Counter from 'components/StoreExample/Counter';
// Actions
import * as counterActions from 'stores/modules/example/counter.module';
class CounterContainer extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<Counter
number={number}
onPlus={CounterActions.increment}
onSubtract={CounterActions.decrement}
/>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
number: state.counter.number
};
};
const mapDispatchToProps = (dispatch) => {
return {
CounterActions: bindActionCreators(counterActions, dispatch)
};
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(CounterContainer);
예제와 같이 두 컴포넌트는 명확하게 역활이 분담되어 있고, 이렇게 분리된 프레젠테이셔널 컴포넌트와 컨테이너 컴포넌트는 따로 여러가지 곳에서 재사용이 용이하게 됩니다.
해당 패턴은 리덕스를 개발한 Dan Abramov가 고안한 패턴입니다.
medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
반응형
'Front-end > React.js' 카테고리의 다른 글
[REACT] Redux란? (0) | 2021.05.05 |
---|---|
[REACT] CRA를 통한 리액트 프로젝트 세팅하기 (0) | 2021.04.01 |
[REACT] React Hooks 란? (0) | 2021.03.15 |
Comments