[React] Container(smart component) vs Component(dumb component)

2019. 5. 20. 07:59Web/React.js

참고로 제 프로젝트의 폴더 구조는 아래와 같습니다. 개념 위주로 포스팅을 하다보니, 생략한 부분이 어느정도 있습니다. 궁금한 점은 댓글 남겨주시면 답변 드리겠습니다^^ (광고도 한번씩 클릭해주시면 감사하겠습니다 ㅠㅠ ㅋㅋㅋㅋㅋ)


이전 포스팅에서 잠깐 언급하기도 했고, 보통 폴더 구조에도 containers 폴더와 components 폴더로 나눈 게 된다.

각각의 개념과 역할에 대해서 알아보자.

  1. Container(smart component)
    • Smart component 또는 Container라고 불림
    • 앱의 상태(Redux state)를 제어하는 역할
    • Redux의 store 접근은 오직 container를 통해서만 이루어진다.
  2. Component(dumb component)
    • Dumb component 또는 Presentional component라고 불림
    • 상위 component로부터 props를 전달받아 보여주는 역할

그렇다.. 쉽게 말해서 container가 일은 다하고, component는 받아서 보여주기만 하는 역할을 한다...
예제를 통해서 좀 더 자세히 보자

// container 예제
// PoiSearchContainer.js
...
render () {
    const { poiResults, loading, failure } = this.props;
    const { handleChange } = this;

    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return (
      <div className="PoiSearchContainer">
        <SearchForm label='origin' placeholder='POI Search...' handleChange={handleChange}></SearchForm>
        <SearchForm label='destination' placeholder='POI Search...' handleChange={handleChange}></SearchForm>
        { !loading && !failure && poiResults && <PoiSearchResultContainer poiResults={poiResults} /> }
      </div>
    );
  }
}

export default connect(
  (state) => ({
    poiResults: state.poi.get('poiResults'),
    loading: state.pender.pending['SEARCH_POI'],
    failure: state.pender.failure['SEARCH_POI']
  }),
  (dispatch) => ({
    PoiActions: bindActionCreators(poiActions, dispatch)
  })
)(PoiSearchContainer);
// component 예제
// SearchFrom.js
render() {
    const { label, placeholder, handleChange } = this.props;

    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return (
      <div className="searchFormWrapper">
        <Input fluid labelPosition="left">
          <Label basic className="labelName">
            {label}
          </Label>
          <Input
            icon={{ name: 'location arrow', inverted: true, circular: true, link: true }}
            placeholder={placeholder}
            className="searchInput"
            onChange={handleChange}
          />
        </Input>
      </div>
    );
  }

위 예제에서 첫번째 코드가 container이고, 두번째 코드가 component이다.
Poi 검색을 위한 component 예제이며, PoiSearchContainer 안에 SearchForm component가 들어있다.
store 접근이 연동된 부분은 오직 container인 PoiSearchContainer에만 있고 이것을 SearchFrom에 props로 전달한다.
SearchFrom에는 상위 컴포넌트인 PoiSearchContainer로부터 props를 전달받아 렌더링하는 역할만 하는 것을 볼 수 있다.