참고 링크
- Presentational and Container Components
- 멍청한 컴포넌트 (presentational) :
components
- 똑똑한 컴포넌트 :
container
코드 작성 패턴
멍청하고 똑똑하다는 건 추상적인 의미이다.
컨테이너 ↔ 컴포넌트
container
state
를 지닐 수 있다.
- 실제
기능을 수행하는 함수
와 프로세싱 작업이 수행된다. (실질적인 기능 수행)
- 구조 틀을 잡는 것 외에 절대로 별도의 스타일(css)를 가지지 않는다.
components (Presentational components)
- 오직
props
로 전달받은 값을 렌더링하는 것을 목표로 함 (단순히 보여주는 용도)
data
와callback
함수들은prop
으로 받아서 사용함.- 반드시 필요할 때만 프레젠테이셔널 컴포넌트에서 state를 가짐.
- 구체적인 스타일 정의
- 구조 정의
- 라이프사이클 함수와 상태 관련 함수들에 관여받지 않기 위해 함수형으로 작성함.
코드 분리 예시
컨테이너
src/containers/HeaderContainer.js
- 컴포넌트가 사용할 기능과, 기능에 필요한 변수들만 설정함
- 실제 필요한 기능
- 리덕스와 소통할 dispatch
- 시각적인 부분은 정의하지 않음
- 기능만 정의하고, 그걸 실제 나타날 컴포넌트에게 기능을 전달함.
⇒ 사용은 컴포넌트에서 하나, 실제 정의된 내용은 컨테이너에 있는 것임.
import React from "react"; import { useSelector, useDispatch, shallowEqual } from "react-redux"; import Header from "@/components/common/Header/Header"; import { logout } from "@/modules/common/auth"; import { useHistory } from "react-router-dom"; import { changeSidebar } from "@/modules/common/page"; const HeaderContainer = () => { const history = useHistory(); const { user, sideBar } = useSelector( ({ auth, page }) => ({ user: auth.user, sideBar: page.sideBar }), shallowEqual ); const howMany = { tasks: 8, mails: 4, alerts: 5 }; const dispatch = useDispatch(); const onLogout = () => { dispatch(logout()); history.push("/login"); }; const onToggle = () => { dispatch(changeSidebar({ sideBar })); }; return ( <Header user={user} onLogout={onLogout} onToggle={onToggle} howMany={howMany} /> ); }; export default HeaderContainer;
프레젠테이셔널 컴포넌트
src/components/common/Header/Header.js
- 컴포넌트의 실제 보여질 부분만을 정의함
- 기능은 컨테이너에서 정의된 것을 받아와서 사용할 뿐
import React from "react"; import "./header.scss"; import "./dropdown.scss"; import TopMenu from "./TopMenu"; import TopNav from "./TopNav"; import { Link } from "react-router-dom"; //user, onLogout, onToggle, howMany는 기능(함수)이며 이는 컨테이너에서 정의된걸 받아와서 씀. const Header = ({ user, onLogout, onToggle, howMany }) => { return ( <div> <header className="header fixed-top clearfix"> <div className="brand"> <Link to="/adm" className="logo"> <img src="/images/logo.png" alt="" className="image" /> </Link> <div className="sidebar-toggle-box" onClick={onToggle}> <i className="fas fa-bars"></i> </div> </div> <TopMenu howMany={howMany} /> <TopNav user={user} onLogout={onLogout} /> </header> </div> ); }; export default Header;