-
[React.js] Components SeperationFront-End(Web)/React - 프레임워크(React, Next) 2020. 12. 1. 18:44반응형
🤷 React.js 프로그래밍을 위한 다양한 스킬들 - 2
저번 포스팅에서는, React에서 사용하는 Inline Styles과, 객체를 변수에 저장하여 활용하는 방법을 공부했다.
이번엔, 랜딩페이지부터 세세한 컴포넌트까지 다양한 JS파일을 분할하는 패턴에 대해 다뤄보고자 한다.
📒 Presentational Component & Container Component
아래 코드는, 기니피그 제목 및 사진(5초마다 바꿈)을 표현하는 페이지이다.
여기서 표현을 위한 페이지(Parent, Container)에서 각각의 기능을 분할(Child, Presentational)하려고 한다.
import React from 'react'; import ReactDOM from 'react-dom'; const GUINEAPATHS = [ 'https://content.codecademy.com/courses/React/react_photo-guineapig-1.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-2.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-3.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-4.jpg' ]; export class GuineaPigs extends React.Component { constructor(props) { super(props); this.state = { currentGP: 0 }; this.interval = null; this.nextGP = this.nextGP.bind(this); } nextGP() { let current = this.state.currentGP; let next = ++current % GUINEAPATHS.length; this.setState({ currentGP: next }); } componentDidMount() { this.interval = setInterval(this.nextGP, 5000); } componentWillUnmount() { clearInterval(this.interval); } render() { let src = GUINEAPATHS[this.state.currentGP]; return ( <div> <h1>Cute Guinea Pigs</h1> <img src={src} /> </div> ); } } ReactDOM.render( <GuineaPigs />, document.getElementById('app') );
먼저, 각각의 폴더를 만들어야된다. Containers(for Container) 과 Components(for Presentational)에 JS파일을 만든다.
- Presentational Component
프레젠테이션 컴포넌트는 렌더링될 JSX(HTML) 컴포넌트를 포함한다. (직접 렌더링하지 않으므로 ReactDOM 불필요!)
또한, 이것을 컨테이너에서 표현될 수 있도록 export 처리해줘야 한다.
//GuineaPigs.js import React from 'react'; export class GuineaPigs extends React.Component { render() { let src = this.props.src; return ( <div> <h1>Cute Guinea Pigs</h1> <img src={src} /> </div> ); } }
GuineaPigs 컴포넌트에서, 렌더링 메소드 외 다른 요소들은 삭제했다.
또한, src = this.props.src 구문을 통해 img소스를 컨테이너의 state값(이미지 Array들)을 props로 받아 표현한다.
- Container Component
컨테이너 컴포넌트는 스스로를 렌더링해야 한다. 그래서 render() 메소드 안에 프레젠테이션 컴포넌트들이 포함된다.
//GuineaPigsContainer.js import React from 'react'; import ReactDOM from 'react-dom'; import { GuineaPigs } from '../components/GuineaPigs'; const GUINEAPATHS = [ 'https://content.codecademy.com/courses/React/react_photo-guineapig-1.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-2.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-3.jpg', 'https://content.codecademy.com/courses/React/react_photo-guineapig-4.jpg' ]; class GuineaPigsContainer extends React.Component { constructor(props) { super(props); this.state = { currentGP: 0 }; this.interval = null; this.nextGP = this.nextGP.bind(this); } nextGP() { let current = this.state.currentGP; let next = ++current % GUINEAPATHS.length; this.setState({ currentGP: next }); } componentDidMount() { this.interval = setInterval(this.nextGP, 5000); } componentWillUnmount() { clearInterval(this.interval); } render() { const src = GUINEAPATHS[this.state.currentGP]; return <GuineaPigs src={src} />; // Presentational + props } } ReactDOM.render( <GuineaPigsContainer />, // Container document.getElementById('app') );
render() 메소드를 <Guineapigs src={src}> 프레젠테이션으로 대체했다.
또한, state의 interval 변화를 src props로 하달하여 이미지를 변경 처리도록 했다.
컨테이너는 state의 관리와 전달만, 프레젠테이션에서 표현을 담당하도록 컴포넌트를 나누는 기본 원리를 알았다.
그래도, 컨테이너에 state 로직이 많아지면 용량이 커질 것 같다고 생각되는데.. 추후 프로젝트를 진행하면서 컴포넌트 분할방법을 세세히 익혀가야겠다.
반응형'Front-End(Web) > React - 프레임워크(React, Next)' 카테고리의 다른 글
[React.js] React Forms (0) 2020.12.01 [React.js/Side Lib.] PropTypes (0) 2020.12.01 [React.js] Inline Style (0) 2020.11.30 [React.js] Stateful vs Stateless Components (0) 2020.11.29 [React.js] Hooks - useEffect() (0) 2020.11.28