Component 실습
Component 합성
컴포넌트 합성은 여러 개의 컴포넌트를 합쳐서 하나의 컴포넌트를 만드는 것이다.
리액트에서는 컴포넌트 안에도 다른 컴포넌트를 사용할 수 있기 때문에 복잡한 화면을 여러 개의 컴포넌트로 나누어서 구현할 수 있다.
// Welcome.jsx
import React from "react";
const Welcome = (props) => {
return <div>Hello, {props.name}</div>;
};
export default Welcome;
// index.js
...
const App = (props) => {
return (
<div>
<Welcome name="Mike" />
<Welcome name="Steve" />
<Welcome name="Jane" />
</div>
);
};
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Welcome 컴포넌트를 사용해서 컴포넌트 합성을 하는 예제 코드를 보자.
코드를 보면 props의 값을 다르게 해서 Welcome 컴포넌트를 여러 번 사용하는 것을 볼 수 있다.
이렇게 하면 App이라는 컴포넌트는 Welcome 컴포넌트 3개를 포함하고 있는 컴포넌트가 되는 것이다.
이렇게 여러 개의 컴포넌트를 합쳐서 또 다른 컴포넌트를 만드는 것을 컴포넌트 합성이라고 한다.
Component 추출
컴포넌트 합성과 반대로 복잡한 컴포넌트를 쪼개서 여러 개의 컴포넌트로 나눌 수도 있는데, 이러한 과정을 우리는 컴포넌트 추출이라고 부른다.
큰 컴포넌트에서 일부를 추출해서 새로운 컴포넌트를 만든다는 뜻인데, 컴포넌트 추출을 잘 활용하게 되면 컴포넌트의 재사용성이 올라가게 된다.
왜냐하면 컴포넌트가 작아질수록 해당 컴포넌트의 기능과 목적이 명확해지고 props도 단순해지기 때문에 다른 곳에서 사용할 수 있을 확률이 높아지기 때문이다.
재사용성이 올라감으로써 동시에 개발 속도도 향상된다.
다음 예제코드를 보면서 컴포넌트를 추출하는 과정을 하나하나씩 살펴보자.
const Comment = (props) => {
return (
<div className="commentName">
<div className="user-info">
<img src={props.author.avatarUrl} alt={props.author.name} className="avatar" />
<div className="user-info-name">{props.author.name}</div>
</div>
<div className="comment-text">{props.text}</div>
<div className="comment-date">{FormDataEvent(props.date)}</div>
</div>
);
};
먼저 여기에 Comment라는 컴포넌트가 하나 있다.
이 컴포넌트는 댓글을 표시하기 위한 컴포넌트로 내부에 작성자의 프로필 이미지와 이름 그리고 댓글 내용과 작성일을 포함하고 있다.
그리고 이 컴포넌트의 props는 아래 객체와 같은 형태일 것이다.
props = {
author: {
name: "수빡",
avatarUrl: "https://...",
},
text: "댓글입니다.",
date: Date.now(),
};
이제 이 컴포넌트에서 하나씩 컴포넌트를 추출해 보도록 하자.
첫번째는 Avatar 추출이다.
Comment 컴포넌트에서는 이미지 태그를 사용하여 사용자의 프로필 이미지를 표시하고 있는데, 이 부분을 추출해서 Avatar라는 별도의 컴포넌트로 만들어 보자.
const Avatar = (props) => {
return (
<img src={props.user.avatarUrl} alt={props.user.name} className="avatar" />
)
}
추출된 아바타 컴포넌트는 이런 모습이 될 것이다.
그리고 props에 기존에 사용되던 author 대신 조금 더 보편적인 의미를 갖고 있는 user를 사용했다.
보편적인 단어를 사용하는 것은 재사용성 측면을 고려하는 것이라고 보면 된다.
다른 곳에서 이 컴포넌트를 사용할 때도 props에 들어갈 속성들이 의미상 큰 차이 없이 사용할 수 있게 하기 위함이다.
이렇게 추출 된 아바타 컴포넌트를 실제로 코멘트 컴포넌트에 반영 해야한다.
const Comment = (props) => {
return (
<div className="commentName">
<div className="user-info">
<Avatar user={props.author} />
<div className="user-info-name">{props.author.name}</div>
</div>
<div className="comment-text">{props.text}</div>
<div className="comment-date">{FormDataEvent(props.date)}</div>
</div>
);
};
추출된 아바타 컴포넌트가 적용된 코드다.
아바타라는 이름의 컴포넌트로 교최되고 나니 좀 더 코드의 가독성이 높아진 것 같은 기분이 든다.
이제 다음 단계로 사용자 정보를 담고있는 부분을 추출 해보자.
const UserInfo = (props) => {
return (
<div className="user-info">
<Avatar user={props.user} />
<div className="user-info-name">{props.user.name}</div>
</div>
);
};
이 코드는 사용자 정보를 담고 있는 부분을 UserInfo라는 컴포넌트로 추출한 것이다.
아까 처음에 추출했던 아바타 컴포넌트도 여기에 함께 추출된 것을 볼 수 있으며, 그리고 역시 props의 author 대신 좀 더 보편적인 의미를 갖고 있는 user를 사용했다.
그럼 이제 추출된 UserInfo 컴포넌트를 Comment 컴포넌트에 반영해 보자.
const Comment = (props) => {
return (
<div className="commentName">
<UserInfo user={props.author} />
<div className="comment-text">{props.text}</div>
<div className="comment-date">{FormDataEvent(props.date)}</div>
</div>
);
};
UserInfo 컴포넌트를 반영하면 이런 코드가 작성되는데, 코드가 처음에 비해서 훨씬 더 단순해진 것을 볼 수 있다.
컴포넌트를 어느 정도 수준까지 추출하는 것이 좋은지에 대해 정해진 기준은 없지만, 기능 단위로 구분하는 것이 좋고 나중에 곧바로 재사용이 가능한 형태로 추출하는 것이 좋다.
지금 살펴본 예제에서 추출한 Avatar 컴포넌트나 UserInfo 컴포넌트는 다른 웹사이트를 만들 때에도 충분히 재사용이 가능할 것이다.
그리고 앞에서 말했던것처럼 재사용이 가능한 컴포넌트를 많이 가지고 있을수록 개발 속도가 굉장히 빨라지게 된다.
실습 코드는 아래에서 chapter_05_02 디렉토리를 확인하시면 된다.
https://github.com/SoominYim/soaple-react/tree/main/src
'밥줄 > React' 카테고리의 다른 글
[React] React 에러 해결 - Component Key (2) | 2024.11.04 |
---|---|
[React] React 학습 (6) - State & Lifecycle (2) | 2024.11.04 |
[React] React 학습 (4) - Props (4) | 2024.10.31 |
[React] React 학습 (3) - Component (0) | 2024.10.24 |
[React] React 학습 (2) - (JSX, Elements) (3) | 2024.10.22 |