728x90
Components
- 리액트는 컴포넌트 기반의 구조이다.
- 리액트는 모든 페이지가 컴포넌트로 구성되어 있다.
- 하나의 컴포넌트 다른 여러 컴포넌트의 조합으로 구성될 수 있다.
- 마치 레고 블록을 조립하듯이 컴포넌트를 모아서 새로운 컴포넌트를 개발한다.
- 하나의 컴포넌트를 반복적으로 사용함으로써 전체 코드의 양을 줄일 수 있다.
- 이를 통해 자연스럽게 개발 시간과 유지보수 비용을 줄일 수 있다.
- 자바스크립트의 함수와 비슷하다. 입력을 받아 정해진 출력을 내보내기 때문이다.
- 그러나, React component에서 입력은 Props이며, 출력은 React element라는 차이점이 있다.
- React component의 역할은 어떤 속성을 입력받아 그에 맞는 React element를 리턴하는 것이다.
- 컴포넌트의 이름은 항상 대문자로 시작해야 한다. 리액트는 소문자로 시작하는 컴포넌트를 DOM 태그로 인식하기 때문이다.
Props
- Property를 줄인 말이다.
- 리액트에서는 속성이란 뜻으로 사용된다.
- 컴포넌트에 전달할 다양한 정보를 담고 있는 자바스크립트 객체이다.
- Component가 Element를 만드는 틀이라고 한다면 Props는 각 Element 안의 들어가는 재료(속성)이라고 할 수 있다.
Props의 특징
- 읽기 전용(Read-Only)이다.(불변)
- 모든 리액트 컴포넌트는 Props를 직접 바꿀 수 없고, 같은 Props에 대해서는 항상 같은 결과를 보여줘야 한다.
Props의 사용법
function App(props) {
return (
<Profile
name="황인팁"
introduction="안녕하세요, 황인팁입니다."
viewCount={1500}
/>
)
}
- JSX를 사용하는 경우 key value 쌍의 형태로 컴포넌트에 props를 넣을 수 있다.
- 위 코드는 App 컴포넌트 안에 Profile 컴포넌트가 있다.
{
name: "황인팁",
introduction: "안녕하세요, 황인팁입니다."
viewCount: 1500
}
- props는 위와 같은 형태의 자바스크립트 객체가 된다.
function App(props) {
return (
<Layout
width={2560}
height={1440}
header={
<Header title="황인팁의 블로그입니다." /> // 컴포넌트 넣기
}
footer={
<Footer />
}
/>
);
}
- 위와 같이 props 중괄호를 사용해서 props의 값으로 컴포넌트도 넣을 수 있다.
- JSX를 사용하는 경우 컴포넌트에 props를 넣을 수 있다.
JSX를 사용하지 않고 컴포넌트에 props를 넣는 경우
React.createElement{
Profile,
{
name= "황인팁",
introduction: "안녕하세요, 황인팁입니다."
viewCount: 1500
},
null // 하위 컴포넌트가 없기 때문에 children에는 null
};
- 이는 JSX를 사용하지 않을 때 예시를 보여준 것이지 실제로 이런 식으로 개발하지 않는다.
Component의 종류
Function Component(함수 컴포넌트)
- 리액트의 컴포넌트를 함수로 생각하면 이해하기 쉽다.
- 클래스 컴포넌트에 비해 간결한 코드 구성을 가지고 있다.
Class Component(클래스 컴포넌트)
- 자바스크립트 ES6의 클래스를 이용하여 만들어진 컴포넌트이다.
- 처음에는 함수 컴포넌트보다 우위에 있었지만 사용하기 불편하여 지금은 거의 사용되지 않는다.
Component 렌더링
- Component가 실제로 화면에 렌더링 되지 않고 Component로부터 나온 Element가 실제 화면으로 보여진다.
- 따라서 렌더링을 위해서는 Component로부터 Element를 만들어야 한다.
function Welcome(props) {
return <h1>안녕, {props.name}</h1>;
}
const element = <Welcome name="황인팁" />;
ReactDom.render(
element,
document.getElementById('root')
);
- 위 코드에서는 Welcome이라는 함수 컴포넌트를 선언하고 있다.
- Welcome name="황인팁"이라는 이름을 가진 Element를 파라미터로 해서 ReactDOM.render() 함수를 호출한다.
- 이렇게 하면 리액트는 Welcome 컴포넌트에 name="황인팁"이라는 props를 호출하고 그 결과로 React element가 생성된다.
- 생성된 React element는 최종적으로 React DOM을 통해 실제 DOM에 업데이트되고 사용자가 브라우저를 통해 볼 수 있게 된다.
Component 합성
- Component 안에 또 다른 Component를 사용할 수 있다.
- 이를 이용해 복잡한 화면 구성을 여러 개의 Component를 활용해 만들 수 있다.
예시
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App(props) {
return (
<div>
<Welcome name="Mike" />
<Welcome name="Steve" />
<Welcome name="Jane" />
</div>
)
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
- 여기서 App은 Welcome Component 3 개를 포함하고 있는 Component가 된다.
- 이처럼 여러 개의 Component를 합쳐 또 다른 Component를 만드는 것을 Component 합성이라고 한다.
- Welcome Components는 각기 다른 props를 가지고 있다.
- 이는 리액트로만 구성된 웹의 기본적인 구성이다.
- 만약 기존에 있던 웹에 리액트를 연동하는 방식이라면 root node가 하나가 아닐 수도 있기 때문에 이런 구조가 아닐 수도 있다.
Component 추출
- Component 합성과는 반대로 복잡한 Component를 쪼개서 여러 개의 Component를 나눌 수도 있다.
- 이를 잘 활용하면 Component의 재사용성이 올라간다.
- Component가 작아질수록 해당 Component의 기능과 목적이 명확해지고 props도 단순해져 다른 곳에서 사용 가능할 확률이 올라간다.
예시
function Commnet(props) {
return (
<div className="comment">
<div className="user-info">
<img className="avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="user-info-name">
{props.author.name}
</div>
</div>
<div className="comment-text">
{props.text}
</div>
<div className="comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
위 Component의 props
props = {
author: {
name: "황인팁",
avatarUrl: "https://...",
},
text: "댓글 내용",
date: Date.now()
}
- Comment Component에서는 img 태그를 사용하여 사용자의 프로필 이미지를 표시한다.
- 이 부분을 추출해서 Avatar라는 별도의 Component를 만들어보자.
Avatar Component 추출하기
function Avatar(props) {
return (
<img className="avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
)
}
- 다른 곳에서 사용할 수 있다는 가능성을 고려하여 author 대신 user로 변경한다.
function Avatar(props) {
return (
<img className="avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
)
}
추출한 Avatar Component를 Comment Component에 반영하기
function Commnet(props) {
return (
<div className="comment">
<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">
{formatDate(props.date)}
</div>
</div>
);
}
UserInfo Comment 추출하기
function UserInfo(props) {
return (
<div className="user-info">
<Avatar user={props.author} />
<div className="user-info-name">
{props.author.name}
</div>
</div>
);
}
추출한 UserInfo Comment Component 반영하기
function Commnet(props) {
return (
<div className="comment">
<UserInfo user={props.author} />
<div className="comment-text">
{props.text}
</div>
<div className="comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
- Component를 어디까지 추출할 것인가에 대해서 정해진 것은 없지만 기능 단위로 구분하는 것이 좋고, 나중에 곧바로 재사용 가능한 형태로 추출하는 것이 좋다.
- 재사용이 가능한 Component를 많이 가지고 있을수록 개발 속도가 빨라진다.
참고
인프런 - 차음 만난 리액트
728x90
'[FrontEnd] > React' 카테고리의 다른 글
React - Hooks (0) | 2023.06.02 |
---|---|
React - State & Lifecycle (0) | 2023.06.02 |
React - Rendering Elements (0) | 2023.06.01 |
React - JSX (0) | 2023.06.01 |
리액트(React) 기초와 관련 용어 정리 (0) | 2023.06.01 |