1. 리액트 소개

25728 단어 ReactReact

모던 리액트(React)와 리덕스(Redux)

강사 Github


보일러 플레이트(Boiler plate)

재사용이 가능하고 적은 수정만으로 여러 곳에 활용할 수 있는 소스 코드


Modern Javascript Tooling

  • 여러 개의 js 파일이 툴링(트랜스파일)을 거쳐 하나의 js파일이 된다.
  • 이 파일이 html, css 파일과 함께 브라우저에서 작동

툴링(Tooling) / 트랜스파일(Transpile)

코드를 같은 수준의 다른 언어로 바꿔주는 과정

  • 웹팩(webpack) + 바벨(babel)
    👉 ES6가 바로 브라우저에서 실행되지 않는 문제를 해결하기 위해 브라우저에서 실행할 수 있는 코드로 변환

개발 환경 및 프로젝트 설정

NPM (Node Package Manager)

자바스크립트 패키지 관리자

  • 자바스크립트 런타임 환경 Node.js의 기본 패키지 매니저
  • node.js를 설치하면 자동으로 설치된다.

리액트 앱 구조

<!--index.html-->
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="/style/style.css">
    ...
  </head>
  <body>
    <div class="container"></div>
  </body>
  <script src="/bundle.js"></script>
</html>
// index.js
// node_modules에 설치된 라이브러리를 가져와서 변수에 할당 
import React from 'react';
import ReactDOM from 'react-dom';

const App = () => {
  return <div>Hi!</div>;
};

// ReactDOM으로 실제 DOM을 렌더링
// 컴포넌트를 실제 인스턴스로 만들어서 클래스가 container인 div에 DOM 렌더링
// <App /> === React.createElement(App)
ReactDOM.render(<App />, document.querySelector('.container'));
  • react 라이브러리는 컴포넌트를 생성하고 관리
    react-dom 라이브러리는 실제 DOM과 상호작용
  • index.js 파일은 어플리케이션의 루트로, 모든 컴포넌트는 여기에 속한다.

컴포넌트

리액트로 만들어진 앱을 이루는 최소한의 단위

  • 데이터(props, state)를 입력받아 DOM Node를 출력
  • 하나의 파일에 하나의 컴포넌트만 만들어야 한다.

JSX

확장 자바스크립트

  • 리액트 element를 생성
  • BABEL: JSX를 바닐라 자바스크립트로 변환

index.html에 포함된 bundle.js는 웹팩과 바벨을 거쳐 하나로 합쳐진 js 파일


컴포넌트 exportimport

  • npm install --save youtube-api-search로 유튜브 검색 API에 필요한 라이브러리 설치
    • --save: package.json에 자동 저장
    • package.json: 프로젝트에 필요한 디펜던시들을 포함하는 파일

export

  • 컴포넌트를 export하면 프로젝트 전체에서 내보낸 컴포넌트를 사용할 수 있게 된다.
import React from 'react';

const SearchBar = () => {
  return <input />;
};

// 컴포넌트 내보내기
export default SearchBar;

💡 export default

참고
모듈(파일) 하나에 하나의 개체만 있다는 사실을 명시

  • 파일 하나에 최대 하나의 export default가 있을 수 있으므로, 내보낼 개체에 이름이 없어도 된다.
  • 이후에 중괄호({}) 없이 사용 가능

import

// npm으로 설치한 모듈 import
import React from 'react';
import ReactDOM from 'react-dom';

// 내가 만든 컴포넌트 import
import SearchBar from './components/search_bar';

const App = () => {
  return (
    <div>
      <SearchBar />
    </div>
  );
};

ReactDOM.render(<App />, document.querySelector('.container'));
  • npm으로 설치한 라이브러리는 패키지명으로 import
    내가 만든 컴포넌트는 경로를 명시하여 import (확장자 .js는 생략 가능)

클래스 기반의 컴포넌트

함수형 컴포넌트

하나의 함수가 JSX를 반환하는 컴포넌트

const SearchBar = () => {
  return <input />;
};

클래스 기반 컴포넌트

ES6의 클래스를 이용한 컴포넌트

  • 모든 클래스 기반 컴포넌트에는 render() 메소드가 정의되어야 한다.
  • state를 파악할 필요가 있는 경우 사용한다.
import React from 'react';

class SearchBar extends React.Component {
  render() {
    return <input />;
  }
}

위의 코드에 문법적 설탕(syntactic sugar)을 가미하면 아래와 같이 쓸 수 있다.

import React, { Component } from 'react';

class SearchBar extends Component {
  render() {
    return <input />;
  }
}

export default SearchBar;

이벤트 핸들링

  1. 이벤트 핸들러 선언
    이벤트 핸들러: 이벤트가 발생할 때마다 실행되는 함수
  2. 선언된 이벤트 핸들러가 필요한 요소에 전달
class SearchBar extends Component {
  render() {
    return <input onChange={this.onInputChange} />;
  }

  onInputChange(event) {
    console.log(event.target.value);
  }
}

위의 코드에서 onInputChange() 함수는 간단하기 때문에 화살표 함수로 아래와 같이 작성할 수도 있다.

import React, { Component } from 'react';

class SearchBar extends Component {
  render() {
    return <input onChange={(event) => console.log(event.target.value)} />;
  }
}

export default SearchBar;

상태(state)

  • 함수형 컴포넌트는 state를 가지지 못하며, 클래스 기반 컴포넌트만 state를 가질 수 있다.
  • state를 사용하기 전에 초기화해야 한다.
    • state를 초기화하는 this.state 구문은 생성자 내부에서만 사용할 수 있다.
  • state가 변경될 때마다 컴포넌트에 자동으로 리렌더링 신호를 보내고, render() 메소드의 업데이트된 정보를 DOM으로 보낸다.

생성자(constructor)

모든 자바스크립트 클래스가 가지는 특수한 함수

  • 새 인스턴스가 생성될 때 자동으로 실행된다.
  • 변수나 상태 값을 초기화하는 일에 주로 사용된다. (이런 작업이 필요없는 경우 구현하지 않아도 됨)
class SearchBar extends Component {
  constructor(props) {
    super(props);

    this.state = { term: '' };	// state 초기화
  }
  render() {
    return (
      <div>
        <input
          onChange={(event) => this.setState({ term: event.target.value })}
        />
      </div>
    );
  }
}
  • 생성자 내부에서는 this.state로 state 값을 초기화할 수 있으며, this.setState()는 사용할 수 없다.
  • 컴포넌트 안 다른 곳에서 this.setState()로 값을 변경할 수 있다.
    • this.state.term = 'aa'; 이런 식으로 변경 ❌
    • setState()는 state 값이 바뀔 때마다 리액트에게 알려주는 역할을 한다.

💡 super(props)를 작성하는 이유

(참고1, 참고2)

  • super()는 부모 클래스의 생성자를 호출하며, 여기서는 Component의 생성자를 호출한다.
  • 이 과정에서 props를 세팅해주기 때문에 super(props)를 호출하지 않으면 this.props를 사용할 수 없게 된다.
  • 당장 this.props를 사용하지 않더라도 이후 디버깅 과정에서 발생할 문제를 위해 항상 super(props)를 호출하는 것이 좋다.

JSX 안에서 자바스크립트 변수를 참조하려면 중괄호({})로 감싸준다.


제어 컴포넌트

  • 사용자가 타이핑을 할 때 inputvalue가 바뀌는 것이 아니라 state가 변경될 때 value가 변경되어 사용자에게 보여지게 하도록 제어
    • input에 기본값을 세팅하거나 할 때 유용
    • inputvalue를 읽어오기가 용이
render() {
  return (
    <div>
      <input
        value={this.state.term}
        onChange={(event) => this.setState({ term: event.target.value })}
      />
    </div>
  );
}

❓🤷‍♀️❓


좋은 웹페이지 즐겨찾기