[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은 이전 엘리먼트와 비교하여 필요한 부분만 업데이트한다.

 

React

 

일반적인 JavaScript로 setInterval() 을 사용하면 아래와 같다.

JavaScript

 

 

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>
  );
}

 

이제 필요한 부분만 가져다 쓸 수 있다.

 

반응형