React에서는 모든 페이지가 컴포넌트로 구성
하나의 컴포넌트는 또 다른 컴포넌트들의 조합으로 이루어짐
컴포넌트를 조립하고 모아서 개발하는 방식 (Like 레고 블록)
![]() | ![]() |
|---|
Component는 Javascript의 함수와 비슷한 방식 → (입력값을 받아 정해진 출력을 내보냄)
React Component는 props를 입력으로 받고, React element를 출력으로 내보냄.
React Component는 속성들(props)을 입력으로 받아 그에 맞는 React element를 생성하여 return 해줌.
React Component가 붕어빵 틀의 개념
React Element가 틀을 이용해서 찍어낸 붕어빵의 개념
객체지향의 Class와 Instance의 관계라고 생각하면 편함.
React Component의 속성(Property), 입력값
Component에 전달할 다양한 정보를 담고 있는 JS 객체
붕어빵으로 비유하자면 붕어빵의 재료에 해당
같은 리액트 컴포넌트에서 눈에 보이는 속성(글자, 색상…)들을 변경하고 싶을 때 사용
![]() | ![]() |
|---|
Read-Only → 값을 변경할 수 없다.
붕어빵에 속재료를 넣고 구웠는데(Component에서 입력된 props를 통해 Element를 만들 때)에 속재료(props)를 슈크림(props.material = “cream”)에서 팥(props.material = “redbean”)으로 갑자기 띠용하고 변경할 수 없는 것
모든 React Component는 props를 직접 바꿀 수 없고 같은 props에 대해서는 항상 같은 결과값(element)을 보여줘야(return해야) 한다. (Pure 해야 한다.)
![]() | ![]() |
|---|
JSX를 사용하지 않아도 props를 사용할 수 있지만 권장하지 않음.
어차피 JSX 방식으로 Component에 props를 넣어 Element를 생성(return)할 때 내부적으로 createElement() 함수를 사용함.
JSX 방식으로 작성하는 게 코드가 더 깔끔하고 가독성이 좋으니 JSX 방식으로 사용하는 것을 권장함.
function App(props){
return (
<Profile
name = '소플'
introduction = '안녕하세요, 소플입니다'
viewCount = {1500}
// 중괄호로 감싸면 JS 코드로 취급됨.
// 문자열을 제외한 다른 자료형(정수, 변수, 다른 컴포넌트)은 중괄호 사용
/>
);
}
/* Profile Component의 props */
{
name: '소플',
introduction : '안녕하세요, 소플입니다',
viewCount : 1500
}
Component는 Function Component와 Class Component로 나뉨.
리액트 초기에는 Class Component를 주로 사용했으나 사용성의 문제로 인해 Class Component보다는 Function Component를 개선하여 주로 사용.
Function Component를 개선하는 과정에서 등장한 것이React Hook임.
Function Component (함수 컴포넌트)
function Welcome(props){
return <h1> 안녕, {props.name}</h1>;
}
Class Component (클래스 컴포넌트)
class Welcome extends React.Component{
render(){
return <h1>안녕, {this.props.name}</h1>;
}
}
```
Component의 이름은 항상 대문자로 시작해야 함. ⭐
// HTML div 태그로 인식
const element = <div />;
// Welcome이라는 React Component로 인식
const element = <Welcome name = "소플"/>
Component 렌더링
실제로 Component 자체가 화면에 렌더링 되는 것은 아님.
Component의 틀을 가지는 element가 렌더링 되는 것
Component 렌더링 예시
// 1. Welcome 컴포넌트 선언
function Welcome(props){
return <h1> 안녕, {props.name}</h1>;
}
// 2. props.name으로 소플이라는 값을 가지는 element를
// Welcome component로부터 생성
const element = <Welcome name = "소플" />
// 3. 생성된 React Element를 React.render함수로 실제 DOM에 렌더링(업데이트)
ReactDOM.render(
element,
document.getElementById('root')
);
여러 개의 Component를 합쳐서 하나의 Component를 만드는 것.
React는 Component안에 또 다른 Component를 쓸 수 있기 때문
복잡한 화면 → 여러 개의 Component로 나누어 구현
Component 합성 예시
function Welcome(props){
return <h1>Hello, {props.name}</h1>;
}
// 각각 다른 props를 지닌 Welcome Component(element) 3개로 이루어진 App Component
function App(props){
return(
<Welcome name = "Soaple"/>
<Welcome name = "Steve"/>
<Welcome name = "Michael"/>
);
}
ReactDOM.render(
<App/>
document.getElementById('root')
);
큰 컴포넌트에서 일부 작은 컴포넌트를 추출하여 새로운 컴포넌트를 만드는 것.
컴포넌트 재사용성 ⬆️, 개발 속도 ⬆️
Component 추출 예시
// Component 추출 전
function Comment(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 추출 후 */
// 1. Avatar Component 추출
function Avatar(props){
return(
<img className = "avatar"
src = {props.user.avatarUrl},
alt = {props.user.name}
{/* 재사용성을 측면을 높이기 위해 보편적인 단어인 user를 사용 */}
/>
);
}
// 2. UserInfo 추출하기
function UserInfo(props){
return(
<div className = "user-info">
{/* 이미 추출한 Avatar Component도 적용 */}
<Avatar user = {props.user} />
<div className = "user-info-name">
{props.user.name}
</div>
</div>
);
}
// 3. 추출한 Component들로 Comment 재합성
function Comment(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를 많이 가지고 있을수록 개발 속도는 빨라진다!
인용 자료 출처
처음 만난 리액트