소개글
과연 객체지향, OOP에서 말하는 객체와 React Component를 동일선 상에 놓고 봐도 되는가?
KUIT 교내 개발 동아리에서 WEB 파트장을 하다 이런 질문을 받게 되었다. 좋은 질문을 남겨준 이름 모를 부원 분께도 감사하며, 파트장을 하며 오히려 알아가는 것이 많아 힘들지만 재밌다.
지금까지 받은 질문 중에서 가장 많이 찾아보고 고민했음에도, 아직까지 스스로 명확한 답을 내리지 못한 상태이다. 이 질문 덕에 React 공식 문서부터 각종 번역본, React 개발자 분의 블로그(overreact)까지 탐독하게 되었다.
(이 글을 읽는 다른 개발자 분들의 의견도 매우 궁금한 상황이고 틀린 내용이 있다면 꼭 댓글 달아 주시면 정말 감사하겠습니다!!)
JS Deep Dive 책을 다 읽고 이해한다면 더 깔끔한 답변이 가능할거라 느꼈고, JS Deep Dive를 다 읽고나서 이 글을 다시 볼 생각이다. 아래는 질문과, 답변했던 내용을 경어체 그대로 옮겨와보았다.
질문
리액트를 공부하다가 의문이 생겨서 질문드립니다.
리액트의 가장 기본 단위는 Component라고 하는 것 같은데, 이 Component는 행동(이벤트 핸들러나 로직처리 부분)과 상태로 구성되는 것이라고 배웠습니다.
사실상 UI 출력도 어떻게 보면 출력을 하는 "행동"으로 볼 수 있을 것 같은데, 그러면 OOP에서 말하는 "객체"와 크게 다르지 않은 건가요??
둘 다 독립적인 단위로서 행동과 상태로 구성되니까요.. GPT는 객체와 컴포넌트는 그 개념이 사실상 동일하지만 사용되는 관점과 맥락에 따라 용어가 다를 뿐인 것이라고 하는데, 의견이 궁금합니다.
만약에 객체와 컴포넌트가 동일한 것이라면, 객체는 익숙한 개념이라 컴포넌트를 객체로 바라보면서 학습하면 좀 더 쉬워질 것 같아 질문드립니다
답변
먼저 객체지향, OOP는 패러다임의 한 분야입니다. OOP의 특징으로는 추상화, 상속, 다형성, 캡슐화가 있죠.
React component는 UI를 추상화하기 위한 목적으로 만들어졌고, 자식 컴포넌트도 만들어 data를 전달할 수 있고, 데이터를 캡슐화 가능하며, Typescript를 통해 다형성도 만족시킬 수 있습니다.
그런데 상속 구조보다는 합성을 사용하는 걸 권장하네요. 그리고 props를 통한 data도 한 쪽 방향으로밖에 전달하지 못합니다.
React는 객체지향을 목적으로 만들어진 것은 아니고 선언적 패러다임을 통해 UI를 더 쉽게 만들기 위한 목적으로 만들어졌다고 생각합니다. 개발자가 UI 랜더링에 대한 책임은 React한테 위임하고, 컴포넌트만 선언하면 되는 것이죠.
React 코드를 잘 작성하고, component를 잘 설계하고 관리하기 위한 방법을 생각하다 보니 OOP와 비슷해지게 되고, SOLID와 같은 OOP 원칙들을 가져와서 적용하게 된 것이 아닌가 싶습니다.
유명한 객체지향 원칙인 SOLID를 React에서 어떻게 적용하는지는 이 글을 참고하면 좋습니다.
원래 React는 class component 생성 방식을 따르다 v16.8에서 hook이 등장하면서 현재는 function component 생성 방식으로 바뀌었습니다. 이 이유도 개발자에게 더 추상화되고 편리한 UI 개발 환경을 제공하기 위해서라고 생각합니다.
class component를 만들기 위해서는 function 방식보다 알아야 하는 것도 많고, component lifecycle도 상당히 복잡했었거든요.
그리고 Javascript 언어는 클래스 기반 객체지향을 지원하는 JAVA와 달리 프로토타입 기반 객체지향 패러다임을 따르고 있습니다.
그래서 이런 여러가지 이유를 보아 컴포넌트 == (객체 지향에서 말하는) 객체 라고 단정지어 말하기는 어렵다고 생각합니다. component들이 객체의 몇몇 특성을 띠고, 일부 OOP 패러다임을 차용해 쓰고 있다 라고 생각하는 것이 어떨까 싶습니다.
저도 고민하던 부분이어서 이리저리 많이 찾아보긴 했는데 내용은 많이 없는 것 같네요..
추가내용
React를 처음 시작하는 부원 분이 헷갈리실까봐 답변 내용에는 달지 않았지만 내용을 추가해본다면 다음과 같다.
Javascript는 프로토타입 기반 객체지향이라 사실 function도 객체이고, 이에 따르면 component도 객체라고 부를 수 있다. 여기서부터 아주 혼란스러워졌다. 그러면 일반적인(JAVA, C++) 객체 지향과 뭐가 다르지? 프로토타입은 도대체 뭐지? 함수형 프로그래밍(FP)??
이 차이에 대해서는 Javasript Deep Dive 책에 자세히 나와있고, 마침 해당 책 스터디도 하게 되었으니 여기서 여러 의견을 나누고 깊게 학습할 것이 기대된다.
아직 JS에 대한 이해가 완벽하지 않아 헷갈리고 잘 모르는 부분이 많았고, 나중에 다시 봤을 때 더 많은 내용을 보충할 수 있길 기대하며 글을 마친다.
<참고 문서들>
- https://legacy.reactjs.org/blog/2013/06/05/why-react.html
- https://medium.com/@admin_1497/리액트-개발자는-객체지향-패러다임을-적용할-수-없는걸까-부제-리액트에서-객체지향-프로그래밍-31fc98f7c5fb
- https://overreacted.io/why-do-we-write-super-props/
- https://overreacted.io/how-does-react-tell-a-class-from-a-function/
- https://pozafly.github.io/react/declarative-meaning-of-react-rendering-process/
- https://velog.io/@cychann/React-Class-컴포넌트-vs-Function-컴포넌트
- https://kciter.so/posts/polymorphic-react-component/
- https://react.dev/learn/thinking-in-react
'프로그래밍 > Frontend (React, Javascript, Typescript)' 카테고리의 다른 글
전역 상태(zustand)에서 배열 concat의 side effect, 해결 방안 (feat. React Strict Mode) (0) | 2024.12.15 |
---|---|
Vite Proxy with Base URL & CORS 해결 (2) | 2024.11.28 |
10분 만에 웹사이트에 PWA 적용해서 웹앱 만들기! (2) | 2024.11.14 |
Fixed Menu, 메뉴 바 상단 고정 구현 시 content에 margin-top을 주면 위험한 이유 (feat. margin collapsing) (4) | 2024.09.28 |
[JavaScript, Node.js] 프론트엔드(JavaScript Runtime)에서의 Race Condition (0) | 2024.04.11 |