ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 혼자 공부하는 자바스크립트 10장 - 리액트
    자바스크립트/혼자 공부하는 자바스크립트 2021. 8. 16. 19:33

    리액트

    리액트는 자바스크립트 라이브러리로, 사용자 인터페이스(UI)를 쉽게 구성할 수 있도록 도와준다. 리액트 라이브러리를 사용하면 대규모 프론트엔드 웹 앱을 체계적으로 개발할 수 있으며, 리액트 네이티브를 활용해 스마트폰에서도 빠른 속도로 작동하는 애플리케이션을 만들 수 있다.

     

    리액트 라이브러리 사용 준비하기

    가장 기본적인 방법은 HTML에서 react.development.js, react-dom.development.js, babel.min.js 세 개의 자바스크립트를 읽어들이는 것이다. 앞의 두개는 리액트를 사용하기 위해 필요하고, babel은 리액트 코드를 쉽게 작성할 수 있게 해준다.

    <head>
      <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
      <script src="https://unpkg.com/babel-standalone@6.26.0/babel.min.js"></script>
    </head>
    <body>
      <div id="root"></div>
      <script type="text/babel">
          <!-- 리액트 코드 -->
      </script>
    </body>

    리액트 라이브러리는 단순한 자바스크립트가 아니라, 리액트를 위해서 개발된 자바스크립트 확장 문법(JSX)을 사용한다. 이러한 문법을 사용하려면 바벨이라는 라이브러리를 추가로 읽어들이고 바벨을 적용할 부분을 지정해야 한다. 바벨이 JSX 코드를 읽고 일반적인 자바스크립트 문법으로 변환한 뒤 실행하게 된다.

     

    루트 컴포넌트 출력하기

    리액트에서는 화면에 출력되는 요소를 컴포넌트라고 부른다. 가장 최상위에 배치하는 컴포넌트는 루트 컴포넌트라고 부른다. 컴포넌트를 만들 때엔 HTML 요소를 만드는 것과 동일한 문법을 사용한다.

    <컴포넌트></컴포넌트>

    이렇게 생성한 컴포넌트를 출력할 때는 ReactDOM.render() 메소드를 사용한다 .

    ReactDOM.render(컴포넌트, 컨테이너)

     

    컨테이너는 컴포넌트를 출력할 상자라고 생각하면 된다.

    const component = <h1>리액트 기본</h1>;
    const container = document.getElementById("root");
    
    ReactDOM.render(component, container);

    script[type="text/babel"] 안에 위 코드를 작성하면 div#root 안에 작성한 h1 태그가 작성된 것을 확인할 수 있다.

     

    JSX 기본 문법

    JSX 문법은 단순 태그 생성 외에도, 태그 내부에 표현식을 삽입해서 출력하는 기능도 제공한다. 표현식을 출력할 때는 따옴표를 사용하지 않은, 중괄호 {}를 사용한다.

    <태그>{표현식}</태그>
    <태그 속성={표현식} />
    const name = "구름";
    const width = Math.ceil(Math.random() * 1000);
    const height = Math.ceil(Math.random() * 1000);
    const imgUrl = `http://placedog.net/${width}/${height}`;
    
    const component = (
      <div>
        <h1>{name}님 안녕하세요!</h1>
        <img src={imgUrl} />
        <p>
          {width} * {height}
        </p>
      </div>
    );
    
    const container = document.getElementById("root");
    
    ReactDOM.render(component, container);
    귀여운 댕댕이

    책의 예제는 좀 다른데, 지난 주에 했던 고양이 예제랑 비슷한 느낌이어서 살짝 응용해봤다. 고양이만큼 강아지도 귀엽다.

     

    클래스 컴포넌트

    HTML 표준에 포함된 태그 외에도 사용자가 직접 클래스 또는 함수를 이용해 컴포넌트를 만들 수 있다. 클래스로 컴포넌트를 만들면 클래스 컴포넌트, 함수로 컴포넌트를 만들면 함수 컴포넌트라고 부른다.

    class 컴포넌트 extends React.Component {
      render () {
        return <h1>출력할 것</h1>
      }
    }

    React.Component 클래스의 상속을 받아야 컴포넌트로 동작할 수 있게 하는 속성과 메소드를 받을 수 있다. React.Component 클래스는 출력할 때 render() 메소드를 호출하는데, 이를 오버라이드해서 원하는 것을 출력한다.

     

    class App extends React.Component {
      render() {
        return <h1>리액트 기본</h1>
      }
    }
    
    const container = document.getElementById("root");
    ReactDOM.render(<App />, container);

    클래스 컴포넌트를 사용하면 클래스 메소드 내부에서 this.props 속성을 사용할 수 있다. 이 속성은 컴포넌트를 선언할 때 전달한다.

    class App extends React.Component {
      render() {
        return (
          <div>
            <h1>{this.props.name}님 안녕하세요!</h1>
            <img src={this.props.imgUrl} />
          </div>
        );
      }
    }
    
    const container = document.getElementById("root");
    ReactDOM.render(
      <App name="구름" imgUrl="http://placedog.net/400/200" />,
      container
    );

     

    컴포넌트의 기본적인 속성과 메소드

    React.Component 클래스는 다음과 같은 여러 속성과 메소드를 제공한다.

    class App extends React.Component {
      constuctor (props) {
        super(props)
        // 생성자 코드
      }
    
      render() {
        // 출력할 것
      }
    
      componentDidMount() {
        // 컴포넌트가 화면에 출력될 때 호출
      }
    
      componentWillUnmount() {
        // 컴포넌트가 화면에서 제거될 때 호출
      }
    }

    변경해서 사용할 수 있는 속성으로는 state 속성이 있다. state 속성에는 출력할 값을 저장하며, state 속성 값을 변경할 때는 반드시 setState() 메소드를 사용한다.

    this.state = { 속성: 값 }
    this.setState({ 변경할속성: 값})

     

    지금까지의 내용을 종합해 현재 시간을 출력하는 프로그램을 짜면 다음과 같다:

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          time: new Date(),
        };
      }
    
      render() {
        return <h1>{this.state.time.toLocaleTimeString()}</h1>;
      }
    
      componentDidMount() {
        this.timerId = setInterval(() => {
          this.setState({
            time: new Date(),
          });
        }, 1000);
      }
    
      componentWillUnmount() {
        clearInterval(this.timerId);
      }
    }
    
    const container = document.getElementById("root");
    ReactDOM.render(<App />, container);
    • 현재 시간을 출력하므로 state 속성에 시간을 저장한다.
    • 출력할 것에 state 속성에 있는 값을 지정한다.
    • setInterval() 메소드를 사용해 1초마다 setState() 메소드를 실행시켜 state 속성을 새 시간 값으로 변경한다.
    • componentWillUnmount() 메소드는 굳이 오버라이드 할 필요가 없지만, 다른 곳에서 활용할 경우를 대비해 구현하였다.

     

    이벤트 연결하기

    컴포넌트에 이벤트를 연결할 때는 (1) 메소드 선언, (2) 메소드에 this 바인드, (3) render() 메소드에서 출력하는 태그의 이벤트 속성에 메소드를 입력해 이벤트를 연결한다.

    class App extends React.Component {
      constructor (props) {
        super(props);
        this.메소드 = this.메소드.bind(this)
      }
    
      render () {
        return <h1 이벤트={this.메소드}></h1>
      }
    
      메소드(event) {
        // 이벤트 호출될 때 실행할 코드
      }
    }

    this.메소드 = this.메소드.bind(this) 코드는 리액트에서 이벤트를 연결할 때 반드시 사용해야 한다. 사용하지 않을 시 이벤트 핸들러에서 this 를 입력했을 때 undefined 혹은 window 객체가 나온다.

     

    class App extends React.Component {
      constructor (props) {
        super(props);
        this.state = {
          count: 0
        }
        this.countUp = this.countUp.bind(this)
      }
    
      render() {
        return <div>
            <h1>클릭한 횟수: {this.state.count}</h1>
          <button onClick={this.countUp}>클릭</button>
        </div>
      }
    
      countUp (event) {
        this.setState({
          count: this.stae.count + 1;
        })
      }
    }

    onClick 이벤트 이름을 작성할 때 대소문자를 확실히 지켜서 입력해야 한다.

     

    스타일 지정하기

    style 속성에 객체를 지정하면 스타일을 지정할 수 있다.

    render () {
      const style = {
        color: red;
      }
      return <h1 style={style}>글자</h1>
    }

     

    컴포넌트 배열

    리액트는 컴포넌트를 요소로 갖는 배열을 사용해 한 번에 여러 개의 컴포넌트를 출력할 수 있다.

    class App extends React.Component {
      render() {
        const list = [
          <li>사과</li>,
          <li>바나나</li>,
          <li>배</li>,
          <li>귤</li>,
        ];
    
        return <ul>{list}</ul>;
      }
    }

    일반적으로 this.state에 값 배열을 만들고 render() 메소드 내부에 map() 메소드를 사용해 컴포넌트 배열로 변환 출력하는 코드를 많이 사용한다.

    class App extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          fruits: ["사과", "바나나", "배", "귤"],
        };
      }
    
      render() {
        const list = this.state.fruits.map((item) => {
          return <li>{item}</li>;
        });
    
        return <ul>{list}</ul>;
      }
    }
    render() {
      return (
        <ul>
          {this.state.fruits.map((item) => {
            return <li>{item}</li>;
          })}
        </ul>
      );
    }

     

    리액트와 데이터

    여러개의 컴포넌트 사용하기

    지금까지는 App 컴포넌트 하나만 선언해 활용했지만, Item 컴포넌트를 추가로 만들어 다음과 같이 함께 사용할 수 있다.

    class App extends React.Component {
      render() {
        return (
          <ul>
            <Item value="Item 컴포넌트 1번" />
            <Item value="Item 컴포넌트 2번" />
            <Item value="Item 컴포넌트 3번" />
          </ul>
        );
      }
    }
    
    class Item extends React.Component {
      constructor(props) {
        super(props);
      }
    
      render() {
        return <li>{this.props.value}</li>;
      }
    }

    App 컴포넌트에서 Item 컴포넌트로 value 속성을 전달하고, Item 컴포넌트에서 value 속성을 출력하는 것을 확인할 수 있다.

    댓글

Designed by Tistory.