
[React] 튜토리얼 자습하기 (2)
Lpla
·2021. 10. 7. 23:22
주요 개념
1. Hello World
React에서 Hello Word를 출력하는 방법은 아래와 같다.
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
2. JSX 소개
React는 마크업과 로직을 분리하지 않고 둘 다 포함하는 컴포넌트 단위로 이루어진다.
a. JSX에 표현식 포함하기
중괄호에 변수를 감싸는 방법으로 JavaScript 표현식을 사용할 수 있다.
const name = 'Ji Woon';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(
element,
document.getElementById('root')
);
b. JSX도 표현식이다.
JSX 자체에 JavaScript 조건문이나 반복문을 사용할 수 있다.
function formatName(user) {
return user.firstName + ' ' + user.lastName;
}
const user = {
firstName: 'Ji Woon',
lastName: 'Kang'
};
function getGreeting(user) {
if (user) {
return <h1>Hello, {formatName(user)}!</h1>;
}
return <h1>Hello, Stranger.</h1>;
}
ReactDOM.render(
getGreeting(user),
document.getElementById('root')
);
C. 단일 태그 닫기
단일 태그를 사용할 경우 반드시 /> 로 닫아야 한다.
그렇지 않으면 에러가 발생한다.
const imageIrl = 'https://source.unsplash.com/random/400x400';
const element = <img src={imageIrl} />;
ReactDOM.render(
// getGreeting(user),
element,
document.getElementById('root')
);
D. React.createElement()
Babel은 JSX를 React.createElement() 호출로 컴파일 한다.
아래 두 코드는 동일하다.
JSX 사용O
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
JSX 사용X
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
3. 엘리먼트 렌더링
엘리먼트는 React 앱의 가장 작은 단위다.
엘리먼트는 화면에 표시할 내용을 기술한다.
const element = <h1>Hello, world</h1>;
a. DOM에 엘리먼트 렌더링하기
HTML을 하나 만든다.
<div id="root"></div>
이 엘리먼트를 React를 사용하여 관리한다고 할 때, 이것을 루트 DOM 노드라고 부른다.
React 엘리먼트를 루트 DOM 노드에 렌더링하려면 React.DOM.render() 를 사용한다.
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
b. 렌더링 된 엘리먼트 업데이트하기
다음은 setInterval() 을 사용하여 매 초마다 React.DOM.render() 를 호출하는 코드다.
function tick() {
const element = (
<div>
<h1>Hello, world!</h1>
<h2>It is {new Date().toLocaleTimeString()}.</h2>
</div>
);
ReactDOM.render(element, document.getElementById('root'));
}
setInterval(tick, 1000);
매 초 루트 DOM 내부를 업데이트하도록 설계했지만 개발자도구를 보면 정확히 변경되는 부분만 업데이트되고 있다.
React DOM은 이전 엘리먼트와 비교하여 필요한 부분만 업데이트한다.
일반적인 JavaScript로 setInterval() 을 사용하면 아래와 같다.
4. Component와 Props
a. 함수 컴포넌트
컴포넌트를 가장 쉽게 정의하는 방법은 JavaScript 함수를 사용하는 것이다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
b. 클래스 컴포넌트
ES6에서 도입된 클래스를 사용하여 컴포넌트를 정의할 수도 있다.
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
c. 컴포넌트 렌더링
지금까지 위에서는 React 엘리먼트를 DOM 태그로 나타냈다.
const user = {
name: 'Ji Woon'
};
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
ReactDOM.render(
Welcome(user),
document.getElementById('root')
);
또는 사용자 정의 컴포넌트로도 나타낼 수 있다.
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Ji Woon" />;
ReactDOM.render(
element,
document.getElementById('root')
);
d. 컴포넌트 추출
다음 컴포넌트를 살펴보자.
function formatDate(date) {
return date.toLocaleDateString();
}
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>
);
}
const comment = {
date: new Date(),
text: 'I hope you enjoy learning React!',
author: {
name: 'Hello Kitty',
avatarUrl: 'https://placekitten.com/g/64/64',
},
};
ReactDOM.render(
<Comment
date={comment.date}
text={comment.text}
author={comment.author}
/>,
document.getElementById('root')
);
이 컴포넌트는 author, text, date를 props로 받고 있는데 일부만 사용하기 불편한 구조로 되어 있다.
재사용하기 좋은 코드로 바꿔보자.
먼저 Avatar 부분을 살펴보면
<img
className="Avatar"
src={props.author.avatarUrl}
alt={props.author.name}
/>
이 코드를 아래 코드로 바꿀 수 있다.
function Avatar(props) {
return (
<img className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
author를 user로 바꾼 이유는 컴포넌트 단위로 봤을 때 user가 더 직관적이기 때문이지 필수는 아니다.
이 방식대로 다른 두 부분도 추출한다.
function formatDate(date) {
return date.toLocaleDateString();
}
function Avatar(props) {
return (
<img
className="Avatar"
src={props.user.avatarUrl}
alt={props.user.name}
/>
);
}
function UserInfo(props) {
return (
<div className="UserInfo">
<Avatar user={props.user} />
<div className="UserInfo-name">{props.user.name}</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>
);
}
이제 필요한 부분만 가져다 쓸 수 있다.