-
[React] React로 범용적인 재사용 컴포넌트 만들어보기Front-end/React 2020. 11. 30. 12:52
컴포넌트
컴포넌트란 독립적인 단위모듈인데요, 이는 말 그대로 독립적으로 사용(수행)할 수 있다는 것을 말합니다.
그런데 뭔가 독립적이란 것이 조금 추상적이라고 느껴지시지 않나요?
그만큼 컴포넌트를 나누는 일은 이 독립이라는 단어를 어떻게 해석하느냐에 따라서 방법이 바뀌게 됩니다.
리액트와 같은 SPA 라이브러리 혹은 프레임워크를 사용하다보면 컴포넌트들을 만들게 되는데요
이렇게 만든 컴포넌트들은 특정 화면에서 사용이 될 것입니다. 이 컴포넌트들은 규모가 작은 애플리케이션에서는 적을 수 있지만 규모가 커질수록 컴포넌트의 갯수와 크기도 비례하여 커지게 될 것입니다.
이에 따라 프론트 개발자는 아마 이런 고민들을 하게 될겁니다...
"음.. 어떻게 하면 컴포넌트를 재사용 할 수 있게 개발 할 수 있을까...?"
"유지보수가 쉽도록 컴포넌트를 만들 순 없을까...?"또한 이런 고민은 프로젝트의 규모나 도메인 등에 따른 관심사의 분리(Separation of concerns)에 영향을 받아 어떻게 개발해야할지, 어떤 방식이 효율적인지에 따라서 방향성을 잡기도 합니다.
별거 아닌 것 같지만 정말 심오한 문제들이죠..🤔
가장 접근하기 편하고 직관적인 방법인 도메인 중심으로 만들어진 컴포넌트를 예로 들자면
.
.
.
딱 봤을때 정말 직관적인게 느껴집니다. 이런 도메인 단위 컴포넌트는 소규모에서는 정말 편하게 개발할 수 있지만,
조금만 규모가 커지더라도 엄청나게 많은 도메인과 디렉토리로 인해 쉽지 않은 개발이 되겠죠?
또한 재사용성에서 본다면 도메인 단위는 그 도메인 단 하나만을 위해 사용되기 때문에 굉장히 떨어지게 될겁니다.
그래서 조금이라도 규모가 있는 프로젝트를 진행한다면 재사용성까지 고려해서 컴포넌트를 구현하는 것이 아무래도 개발 뿐만 아니라 유지보수에서도 편할 것입니다.
최근에는 아토믹 디자인(Atomic Design) 이라는 레이아웃 단위의 컴포넌트로 쪼개서 레고처럼 조립해서 만드는 개발론을 사용하여 많이 개발하는 추세이기도 합니다. 이 부분은 추가로 학습한 후 포스팅 하겠습니다. :)
그래서 재사용 단위의 가장 간단하고 기초적인 부분이기도 하고, 유용하게 사용될 수 있는 컴포넌트를 분리하는 시간을 가져보려고 합니다.
❗️ 이 글은 개인적으로 학습한 정보와 지식을 토대로 작성된 글입니다. 혹시 잘못된 부분이 있거나 수정사항이 있다면 말씀해주시면 반영하겠습니다. 🙏
가장 범용적인 컴포넌트
우리가 프론트 개발을 할 때 가장 범용적으로 쓰이는게 무엇이 있을까요?
도메인에 따라 여러가지가 있겠지만, 항상 사용하는 요소들은 span, p, button, div, img 등이 있습니다.
보면 span과 p는 공통적으로 텍스트를 감싸는 태그인 것을 알 수 있죠? 즉, 이 두개를 한 번에 관리하는 컴포넌트가 있으면 참 편할 것 같다는 생각이 번쩍 듭니다.
한 번 만들어보겠습니다.
Text
import React from 'react'; /** * 텍스트 * @param {tag} 텍스트에 사용할 태그 * @param {className} 클래스명 * @param {children} 텍스트의 내용 */ const Text = ({ tag: Tag = 'span', className, children }) => { return <Tag className={className}>{children}</Tag>; }; export default Text;
보면 porps로 tag와 className, children을 받아오고 있습니다. 여기서 주의깊게 봐야하는 부분이 tag인데요,
tag는 이 컴포넌트를 사용할 때 직접 prop을 통해서 가져오고, 그걸 태그에 동적으로 넣어줌으로서 그려주게 됩니다.
만약 tag를 넘겨주지 않으면 기본적으로 span을 사용하게 하였습니다.
실제로 어떻게 사용되나 볼까요?
import React from 'react'; import Text from './components/Text'; function App() { return <Text>Text 컴포넌트 구현</Text>; } export default App;
prop으로 tag를 p로 넘기게 되면..
import React from 'react'; import Text from './components/Text'; function App() { return <Text tag='p'>Text 컴포넌트 구현</Text>; } export default App;
앞으로 컴포넌트를 개발할 때는 텍스트 태그를 사용할 때 이 Text 컴포넌트 하나만을 가지고 사용하면 되는 것이죠
또 하나의 예를 들어볼까요?
Button
버튼도 텍스트와 크게 다르지 않습니다. 버튼의 기능을 생각해본다면 내부에 텍스트를 가진 하나의 버튼이고, Click 이벤트를 가지고 있으며 특정 타입에 따라 다르게 동작합니다. 이런 특성을 이용하여 한 번 구현해보겠습니다.
import React from 'react'; /** * 버튼 * @param {type} 타입 * @param {className} 클래스명 * @param {width} 넓이 * @param {height} 높이 * @param {margin} 마진 * @param {padding} 패딩 * @param {onClick} 클릭 이벤트 * @param {children} 버튼 내용 */ const Button = ({ type = 'button', className, width, height, margin, padding, onClick, children, }) => { return ( <button type={type} className={className} onClick={onClick} style={{ width, height, padding, margin }}> {children} </button> ); }; export default Button;
위 특성들을 고려하면 children에 대한 스타일이 필요할 것이고, 버튼 타입, 그리고 onClick 이벤트를 받으면 버튼과 동일하겠네요
버튼도 사용해 볼까요?
import React from 'react'; import Button from './components/Button'; import Text from './components/Text'; function App() { return ( <Button padding='10px 20px 10px 20px' onClick={() => console.log('버튼 클릭 완료')}> <Text>버튼</Text> </Button> ); } export default App;
이렇게 내가 원하는대로 바로 사용할 수 있습니다.
현재까지 이정도 규모로 봤을 때는 오히려 불편하고 번거롭기만 할 것 같지만, 컴포넌트가 많아질수록 재사용 할 수 있는 부분이 늘어나 능률이 크게 상승될 것입니다.
'Front-end > React' 카테고리의 다른 글
[React] Context로 언제 어디서든 상태 관리 해보기 (0) 2021.01.01 [React] styled-components로 스타일 적용해보기 (2) 2020.11.30 Webpack으로 React 개발 환경 세팅해보기 (0) 2020.11.30 [React] 라이프 사이클(Life-Cycle) 알아보기 (0) 2020.11.30 [React] state 알아보기 (0) 2020.11.30