| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- 자바
- 알고리즘
- Java
- 백준
- Google Cloud Skills Boost
- MVMM
- GoogleCloudConsole
- til
- AI
- 프로그래머스
- 개념
- sql
- INSERT SELECT
- 자바의 정석
- Error Handling
- 조건문
- 유데미
- javascript
- dangerouslySetInnerHTML
- 회고
- Gemini
- mysql
- 스레드
- RESIGNAL
- 파이썬
- databse
- 유데미코리아
- join
- react
- 스터디윗미
- Today
- Total
휘적이는 기록공간
[React 공식문서] Components와 Props 본문
React 공식문서를 기반으로 작성된 포스팅입니다
컴포넌트는 'prpos'라는 임의의 입력을 받은 후 element를 반환합니다.
함수 컴포넌트와 클래스 컴포넌트
function Welcome(props) {
return <h1>안녕하세요, {props.name}님</h1>;
}
이 함수는 데이터를 가진 하나의 props 객체 인자를 받은 후
element를 반환하는 컴포넌트입니다.
이러한 컴포넌트는 자바스크립트 함수이기 때문에
말 그대로 '함수 컴포넌트'라고 호칭합니다.
const Welcome = (props) => {
return <h1>안녕하세요, {props.name}님</h1>
}
사실 React에서는 ES6의 화살표 함수를 이용한 함수 표현이 잦습니다.
앞의 예시를 화살표함수로 표현하면 위와 같습니다.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
클래스 컴포넌트는 위와 같습니다.
컴포넌트 렌더링
이전까지는 DOM태그만을 이용하여 element를 나타냈습니다.
React element는 사용자 정의 컴포넌트로도 나타낼 수 있습니다.
const element = <Welcome name="Sara" />;
Welcome이라는 태그는 name이라는 type을 가지고 있습니다.
이런 태그를 본 적이 있나요?
이것은 사용자가 만든 컴포넌트 입니다.
이 컴포넌트를 이용해
페이지에 'Hello Sara'를 렌더링해 보겠습니다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
이 예시에서는 다음과 같은 일들이 일어납니다.
- <Welcome name="Sara" /> 엘리먼트로 ReactDOM.render()를 호출합니다.
- React는 {name: 'Sara'}를 props로 하여 Welcome 컴포넌트를 호출합니다.
- Welcome 컴포넌트는 결과적으로 <h1>Hello, Sara</h1> 엘리먼트를 반환합니다.
- React DOM은 <h1>Hello, Sara</h1> 엘리먼트와 일치하도록 DOM을 효율적으로 업데이트합니다.
React가 사용자 정의 컴포넌트로 작성한 엘리먼트를 발견하면
JSX 속성과 자식을 해당 컴포넌트에 단일 객체로 전달합니다.
이 객체를 props라고 합니다.
하나 더 만들어 볼까요?
const element = <KoreanFood name='kimchi' tasty='hot' color='red'/>;
태그명은 KoreanFood이고
name, tasty, color라는 타입을 갖고 있습니다.
props로는 차례대로 kimchi, hot, red를 보내네요.
function KoreanFood(props) {
return <div>
<h1>안녕하세요.</h1>
<p>오늘 소개할 한국 음식은 {props.name}입니다.</p>
<p>이 음식은 좀 {props.tasty}합니다.</p>
<p>색도 {props.color}입니다.</p>
<p>그래도 맛있어요!</p>
</div>
}
const element = <KoreanFood name='kimchi' tasty='hot' color='red'/>;
ReactDOM.render(
element,
document.getElementById('root')
);
-> 결과
https://codepen.io/hihui/pen/eYGMLLV
componet_KoreanFood
...
codepen.io
컴포넌트를 만들 때의 주의사항은
대문자로 시작해야 한다는 것입니다.
이유는 소문자로 시작하여 만들게 된다면
React는 기존에 존재하는 태그 즉 DOM태그로 인식하고 처리합니다.
예를 들어 <div/>태그는 HTML div태그를 나타내지만 <Div/>는 사용자가 만들어낸 컴포넌트입니다.
이것은 규칙이기 떄문에 꼭 지켜야합니다!
컴포넌트 합성
컴포넌트는 자신의 출력에 대한 컴포넌트를 참조할 수 있습니다.
이는 모든 세부 단계에서 동일한 추상 컴포넌트를 사용할 수 있음을 의미합니다.
React 앱에서는 button, form, 화면 등 모든 것들이 흔히 컴포넌트로 표현됩니다.
예를 들어 Welcome을 여러 번 렌더링하는 App 컴포넌트를 만들 수 있습니다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
-> 결과
https://codepen.io/hihui/pen/JjraNBB
componet_mix
...
codepen.io
컴포넌트 추출
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<img className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
이 컴포넌트는
객체 author
문자열 text
날짜 date
를 props로 받은 후 코멘트를 남깁니다.
이 컴포넌트는 구성요소들이 모두 중첩 구조로 이루어져 있어서 변경하기 어려울 수 있으며,
각 구성요소를 개별적으로 재사용하기 힘듭니다.
이 컴포넌트에서 몇 가지 컴포넌트를 추출하겠습니다.
먼저 Avatar를 추출하겠습니다.
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
Avatar는 자신이 comment 내에서 렌더링 된다는 것을 알 필요가 없습니다.
따라서 props의 이름을 author에서 더욱 일반화된 user로 변경하였습니다.
props의 이름은 사용될 context가 아닌 컴포넌트 자체의 관점에서 짓는 것을 권장합니다.
추출한 Avatar를 적용해보겠습니다.
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
다음으로 Avatar 옆에 사용자의 이름을 렌더링하는 UserInfo 컴포넌트를 추출하겠습니다.
function Comment(props) {
return (
<div className="Comment">
<div className="UserInfo">
<Avatar user={props.author} />
<div className="UserInfo-name">
{props.author.name}
</div>
</div>
<div className="Comment-text">
{props.text}
</div>
<div className="Comment-date">
{formatDate(props.date)}
</div>
</div>
);
}
다시 적용해 보겠습니다.
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>
);
}
더욱 단순해졌습니다.
처음에는 컴포넌트를 추출하는 작업이 지루해 보일 수 있습니다.
하지만 재사용 가능한 컴포넌트를 만들어 놓는 것은 더 큰 앱에서 작업할 때 큰 효과를 볼 수 있습니다.
UI 일부분이 여러 번 사용되거나 (Button, Panel, Avatar),
UI일부가 자체적으로 복잡한 경우(App, FeedStory, Comment)에는 별도의 컴포넌트로 만드는 게 좋습니다.
props는 읽기 전용
컴포넌트는 컴포넌트 자체의 porps를 수정해서는 안됩니다.
function sum(a, b) {
return a + b;
}
다음 sum함수를 살펴봅시다.
이런 함수들은 순수 함수라고 호칭합니다.
입력값을 바꾸려 하지 않고 항상 동일한 입력값에 대해 동일한 결과를 반환하기 때문입니다.
반면에 다음 함수는 자신의 입력값을 변경하기 떄문에 순수 함수가 아닙니다,
function withdraw(account, amount) {
account.total -= amount;
}
React는 매우 유연하지만 지켜야하는 한 가지 규칙이 있습니다.
모든 React 컴포넌트는 자신의 porps를 다룰 때 반드시 순수 함수처럼 동작해야 합니다.
물론 애플리케이션 UI는 동적이며 시간에 따라 변합니다.
이런 UI를 변화시키기 위해서는 state라는 개념에 대해 알고있어야합니다.
이 state는 위 규칙을 위반하지 않고
사용자의 액션, 네트워크 응답 및 다른 요소에 대한 응답으로 시간에 따라 자신의 출력값을 변경할 수 있습니다.
'Frontend & Client > React' 카테고리의 다른 글
| [React 공식문서] State와 생명주기 (0) | 2022.01.09 |
|---|---|
| [React 공식문서] element Rendering (0) | 2022.01.02 |
| [React 공식문서] JSX 소개 (0) | 2022.01.02 |
| [TIL] React에서 XSS와 dangerouslySetInnerHTML: 문자열 HTML 렌더링의 안전한 처리법 (0) | 2021.12.16 |