[TIL] 20210506_React

BANSEOK SUH·2021년 5월 6일
0

TIL

목록 보기
9/22
post-thumbnail

리액트를 배우기 시작했습니다.

리액트를 설치하는 것부터 시작해서 천천히 글을 작성하려고 합니다.

React

React를 사용하는 이유

사용자와의 interaction이 많아질수록 데이터의 상태관리가 어려워집니다. 리액트를 포함한 여러 프론트엔드 프레임워크는 이러한 동적 웹 페이지를 효율적으로 관리하기 위해 사용됩니다.

설치

디렉토리에 들어가서 터미널에 다음과 같은 명령어로 리액트를 설치합니다.

npx create-react-app twittler-react

위 명령어를 입력했다면 얼마 지나지 않아서 리액트 프레임워크가 세팅이 될 겁니다.
리액트를 사용할 환경이 준비되는 것이죠.
app.js, index.js를 포함한 여러 파일들과 폴더들이 생성됩니다.
여기서는 자세히 다루지 않겠습니다.


여기서부터는 리액트를 다루면서 알아야 할 중요한 개념들에 대해서 잠깐 이야기하겠습니다.

컴포넌트

컴포넌트란 쉽게 말해서 나만의 HTML 커스텀 태그라고 볼 수 있습니다. 내가 원하는 이름으로 태그를 만드는 것이지요. 그리고 그 컴포넌트가 읽힐 때, 그것을 정의하고 있는 클래스 혹은 함수가 읽힙니다.

아래의 코드는 ReactDom.render() 메서드를 이용하여 Tweetler라는 컴포넌트를 id가 root인 엘리먼트에 append를 하기 위한 코드입니다. Tweetler 컴포넌트는 HTML 태그를 리턴합니다.

ReactDOM.render(
    <Tweetler />,
  document.getElementById('root')
);

이렇듯 리액트에서는 컴포넌트 단위로 개발을 합니다. 컴포넌트를 구성하고 있는 태그 안에 작은 단위의 컴포넌트들이 더 있을 수도 있습니다.

아래부터는 위의 코드에서 호출된 Tweetler 컴포넌트를 쫓아가보겠습니다.


클래스 컴포넌트

컴포넌트는 클래스나 함수로 정의될 수 있습니다.

먼저 위에서 호출되었던 Tweetler 컴포넌트클래스 컴포넌트로 정의해보았습니다.
클래스 컴포넌트는 아래와 같이 표현될 수 있습니다.
영문 대문자로 시작하며, React.Component를 상속받습니다.

// 클래스 컴포넌트
class Tweetler extends React.Component {
  constructor(props) {
    super(props);
    ...
  }
  ...
  // render 메서드는 컴포넌트 실행 시 자동으로 호출되는 메서드인 듯합니다.
  // 컴포넌트는 JSX를 리턴합니다.
  // JSX 안에서 중괄호{}들이 보입니다. 아래에서 다루겠습니다.
  render() {
    return (
      <div>
        <div>작성자: 서반석</div>
        <div id="writing-area">
          <textarea id="new-tweet-content" value={this.state.value} onChange={this.handleChange} />
          <button id="submit-new-tweet" onClick={this.handleSubmit}>새 글 쓰기</button> 
        </div>
        <SingleTweet tweets={this.state.tweets}/>
      </div>
    )
  }  
}

생성자 함수가 보입니다. props를 인자로 갖고 있습니다.
props에 대해서는 아래에서 다루겠습니다.

render 메서드는 컴포넌트 실행 시 자동으로 호출되는 메서드인 듯합니다.
리턴은 JSX 문법을 활용한 태그를 리턴해줍니다.
JSX 역시 아래에서 다루겠습니다.

주목해야 할 부분은, render 메서드에서 리턴되고 있는 SingleTweet이라는 컴포넌트입니다.
Tweetler 컴포넌트 안의 작은 컴포넌트라고 할 수 있겠습니다.
컴포넌트를 만나면 컴포넌트를 정의하고 있는 곳으로 갑니다.

* state를 갖는 컴포넌트를 만들기 위해서는 클래스 컴포넌트로 만들어야 합니다.

SingleTweet이라는 컴포넌트는 함수 컴포넌트로 정의돼있는데, 그 뒤를 따라가보겠습니다.

함수 컴포넌트

함수 컴포넌트는 인자로 props를 받고 있습니다. 클래스 컴포넌트에서는 생성자 함수의 인자로 props를 받았었죠.

아래의 코드는 props를 배열로 받아서, 그 길이만큼 순회하여 태그를 생성하고 리턴해주는 모습입니다.
중간중간에 중괄호{}가 보입니다. 자바스크립트 표현식을 JSX 안에서 사용할 때 쓰는 방법입니다.

// 함수 컴포넌트
function SingleTweet(props) {
  const tweets = props.tweets;

  // map 메서드를 이용해 순회를 하며 배열의 길이만큼 li 태그를 생성해주고 있습니다. JSX 문법으로 되어 있네요.
  let tweet = tweets.map((tweet) => {
    return (
      <li key={tweet.uuid} className="tweet">
        <div className="writer">{tweet.writer}</div>
        <div className="date">{tweet.date}</div>
        <div>{tweet.content}</div>
      </li>
    )
  })

  // 컴포넌트이기 때문에 JSX를 리턴합니다.
  return (
    <ul id="tweets">{tweet}</ul>
  );
}

JSX

드디어 JSX가 등장했습니다.
JSX는 자바스크립트의 확장문법입니다. HTML과 매우 유사하게 생겼습니다. 위 코드를 통해 보았지만, 리액트 컴포넌트에서는 JSX를 리턴해줍니다.

왜 JSX를 사용할까요? JSX 없이 태그 생성할 수 없을까요?
아니요. 물론 있습니다. 다만 코드가 지저분해질 뿐입니다.

JSX 없이 태그를 생성하려면 다음과 같이 해야 합니다.

React.createElement('header', {className: 'blahblah'}... );
React.createElement('p', {claaName: 'blah...'} ... );

이렇게 태그를 생성하면 가독성은 떨어지고 복잡도는 올라가게 됩니다.

하지만 다음과 같이 JSX를 사용하면 가독성은 올라가고 복잡도는 떨어지게 되지요.
JSX를 사용하는 충분한 이유가 되겠네요.

덤으로 알아두면 좋은 것은, JSX로 태그를 생성하게 되면 바벨(Babel)이라는 녀석이 위와 같은 코드로 변환해준다는 것입니다.

아래의 JSX 코드와 위의 코드와 차이가 많이 나지요?

<header className = 'App-container'> ... </header>
<p> ... </p>

아, 여기서 반드시 기억해야 할 JSX의 규칙들이 있습니다.

  1. 반드시 하나의 엘리먼트로 감싸져야 할 것
  2. JSX 내부에서 자바스크립트 코드 사용 시 중괄호 {} 사용할 것
  3. JSX 내부에서는 if문을 사용할 수 없기 때문에 삼항연산자나 &&연산자를 사용할 것
  4. 엘리먼트에 클래스이름 적용 시 className이라는 속성으로 적용할 것
  5. 이벤트 적용시 camelCase로 표기할 것 ex) 태그 안에 클릭 이벤트를 줄 경우 'onClick='

props

위에서 props 라는 단어가 꽤나 자주 나왔습니다.
props는 객체인데요, 컴포넌트에 해당하는 어트리뷰트의 키와 밸류가 객체의 형태로 묶인 것입니다.

위에서 예시로 사용했던 컴포넌트를 가져와봤습니다.
여기서 this.state.tweets는 여러개의 객체가 배열을 이루고 있는 구조입니다.

<SingleTweet tweets={this.state.tweets}/>

SingleTweet이라는 컴포넌트가 tweets라는 키와 {this.state.tweets}라는 밸류로 어트리뷰트를 구성하고 있습니다.
위와 같이 tweets라는 어트리뷰트를 가지고 있는 컴포넌트가 호출된다면, 이 컴포넌트의 props는 어떤 모양을 가질까요?

바로 아래와 같은 모양이 됩니다.

이처럼 태그의 속성이 객체의 모양으로 전달되는 것이 props입니다.

팁!
그렇다면 태그의 속성이 아니라 태그 사이의 내용에 접근할 때는 어떻게 해야 할까요?
바로 props.children이라는 속성을 통해 태그 사이의 값에 접근할 수 있습니다.

profile
HelloBanny

0개의 댓글

관련 채용 정보