React

이동환·2020년 10월 5일
1

TIL

목록 보기
37/74

React(공식문서)

: React는 사용자 인터페이스를 만들기 위한 JavaScript 라이브러리다.
리엑트는 자바 스크립트에서 가장 유명한 라이브러리 중 하나이다. 많은 개발자들이 배우고, 코드 스테이츠에서도 가장 중요한 스프린트라고 강조하고 있다.

리액트를 사용하여 우리가 얻을 수 있는 이익은 HTML 트리구조를 보기 좋게 모듈화 시켜 내가 원하는기능만을 쉽게 가져다가 사용할 수 있다는 장점이 있다. 또한 이렇게 모듈화로 저장을 해두면 유지 보수가 쉬워진다.

리엑트는 JS의 라이브러리지만, JSX라는 자바 스크립트 확장형 문법을 사용하고 있고, 자바 스크립트 문법을 사용하려면 {} 안에서 사용 가능하다.

JSX

: JSX란 리엑트를 쉽고 편하게 사용하게 해주는 자바스크립트 확장 문법이다.
리엑트에서 무조건 JSX를 사용해야하는것은 아니지만, 사용하면 여러가지 장점이 있다.( 자바 스크립트 문법으로도 리엑트를 사용할 수 있지만, JSX를 추천한다.)

JSX 사용시 주의점

  1. 반드시 하나의 엘리먼트로 감싸야한다.
    예)

  2. 내부에 JS 코드를 작성할 수 있는데, 이때 중괄호 안에 작성해야한다.
    예)

  1. JSX내부에서는 if문을 사용 할 수 없다. 그래서 우리는 IIFE 또는 삼항연산자를 사용해야한다.
    예)

  2. 엘리먼트의 클래스 이름을 적을 때,class대신에 className이라고 적는다.
    예)

JSX를 통해 기본 문법 살펴보기

function formatName(user) {
  return user.firstName + ' ' + user.lastName;
}
const user = {
  firstName: 'Harper',
  lastName: 'Perez'
};
const element = (
  <h1>
    Hello, {formatName(user)}!  // { }를 사용하여 JS를 사용 가능하게 한다.
  </h1>
);
ReactDOM.render(      // DOM에 렌더를 시키는 함수
  element,	     //  렌더 함수 첫번째 인자로 내가 넣고 싶은 엘리먼트를 넣는다 
  document.getElementById('root')  // 두번째 인자로 내가 넣을 위치를 정한다.
);

JSX의 props 정의하기

props(속성)에 따옴표를 이용해 HTTML처럼 문자열을 넣을 수 있다.

const element = <div tabIndex="0"></div>;

또 중괄호를 사용하여 JavaScript 표현식을 사용 할 수도 있다.

const element = <img src={user.avatarUrl}></img>;

** 주의
JavaScript 표현식을 삽입할 때 중괄호 주변에 따옴표를 입력하지 마세요. 따옴표(문자열 값에 사용) 또는 중괄호(표현식에 사용) 중 하나만 사용하고, 동일한 어트리뷰트에 두 가지를 동시에 사용하면 안된다.

src=https://www.youtube.com/embed/ + {props.video.id.videoId}

내가 과제를 할때, 어트리뷰트(아래 코드에서는 src를 뜻함)에 어떻게 문자열과 JSX를 같이 넣을 수 있을까 고민했었다. 처음에는 여러가지 시도를 했었다. 예를들어서

 src=https://www.youtube.com/embed/ + {props.video.id.videoId}
 // 또는
 src={"https://www.youtube.com/embed/" + {props.video.id.videoId}}

그러나 이렇게 막 섞거나 더하기를 사용하지않고, 아래의 코드로 사용하여 과제를 해결 할 수 있었다.

src={`https://www.youtube.com/embed/${props.video.id.videoId}`}

JSX를 객체로 나타내기

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
//  ===   (위 아래 코드는 같은것을 나타낸다.)
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

이 아래의 코드는 위의 두 코드와 같지만, 단순 JS로만 작성되어있다.

const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

이렇게 순수 JS 객체로 이해하면, 위의 두 코드를 이해하기 쉽다.

Element(엘리먼트)

: 엘리먼트는 React 앱의 가장 작은 단위이고, 엘리먼트는 화면에 표시할 내용을 기술한다. 주의 할 점은 브라우저 DOM 엘리먼트와 다르게 React 엘리먼트는 '일반 객체(plain object)'이며 불변(immutable) 객체이다.

DOM에 엘리먼트 렌더링하기

// HTML 파일에 `<div>를 생성하고 아이디를 root를 지정한다.
<div id="root"></div>
//
function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toLocaleTimeString()}.</h2>
    </div>
  );
// React 엘리먼트를 루트 DOM 노드에 렌더링하기 위해
// ReactDOM.render()를 사용하여 전달.
  ReactDOM.render(element, document.getElementById('root'));
}
// 1초마다 tick 함수를 실행
setInterval(tick, 1000);

Components and Props

: 컴포넌트란, 우리가 CommonJS에서 배운 모듈과 같은 역할을 한다. 컴포넌트를 만들어 놓으면 우리가 사용하고 싶은곳에서 재사용할 수 있다.
이런 컴포넌트에는 두가지 타입의 컴포넌트가 존재한다. 함수 컴포넌트클래스 컴포넌트다.

두 컴포넌트는 차이점이 있다.

함수 컴포넌트와 클래스 컴포넌트

함수 컴포넌트
: 함수 컴포넌트란, 쉽게 말해 JavaScript 함수를 작성하는 것이다. 주로 인자로 props(속성)을 받는다. 함수컴포넌트는 클래스 컴포넌트와 다르게 state를 가지고 있지 않다.(사실 React Hook에서는 state를 가질 수 있다.)

여기서 props란 코드에 A부분쪽에 적힌 Welcome 엘리먼트의 name과 content를 의미한다. 그래서 props.name 는 DH을 뜻하고 props.contents는 Hi, React를 가르킨다.

props에 알아야할 중요한 특성
1. props는 읽기 전용이다. 다시 말해, 불변성 이기때문에 바꿀 수 없어야한다는 것이다.
2. props는 외부로 전달 받은 값이다.

function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
<Welcome name='DH' content='Hi, React'></Welcome>  // A(props) 
// Hello, DH  

클래스 컴포넌트
: ES6 class를 사용하여 컴포넌트를 정의할 수 있다.

class Welcome extends React.Component {
  constructor(){
    super(props);
    this.state = {
      items: [];
    };
  }
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

** 여기서 중요한점
1. 두 종류 컴포넌트는 항상 대문자로 시작한다. 예) Welcome
2. class 컴포넌트는 내부에 constructor와 render 함수를 가진다.
또 constructor는 super(props)를 받고 this.state를 사용할 수 있다.
render는 렌더해주는 메소드로써 react엘리먼트를 리턴한다.

State and Lifecycle(생명 주기)

: Lifecycle은 우리의 삶과 매우 흡사하다.
컴포넌트들도 중요한 순간을 가지게 되는데

위의 그림을 좀 더 자세하게 다이어그램으로 나타내면 아래와 같은 그림이 된다. 아래의 그림은 외워두는것이 좋다. 아주 중요 !

초보자에게 위의 그림이 무엇을 뜻하는지 이해가 안갈수 있다.
아래는 on/off 버튼을 나타내는 코드이다.

import React from "react";
import ReactDOM from "react-dom";
//
function App() {
  return (
    <div className="App">
      <h1>아래 버튼을 눌러보세요</h1>
      <Button />
    </div>
  );
}
class Button extends React.Component {
  constructor(props) {
    super(props);
    this.state = { isOn: false };
    console.log("constructor로 생성"); 
    // constructor를 생성 할때
    this.handler = this.handler.bind(this);
  }
  handler() {
    this.setState((state) => ({
      isOn: !state.isOn
    }));
  }
  componentDidMount(){
    console.log('화면에 등장(mount)')
  }
  componentDidUpdate(){
    console.log('새로운것 업데이트(update)')
  }
  render() {
    console.log("렌더링!");
    // 렌더링 할때
    return (
      <div>
        <button onClick={this.handler}>{this.state.isOn ? "ON" : "OFF"}</button>
      </div>
    );
  }
}
//
const rootElement = document.getElementById("root");
ReactDOM.render(
  <App />,
  rootElement
);

이렇게 코드만 작성하고 콘솔창을 열어보면 아래와 같은 문구를 볼 수 있다.

먼저 constructor에 있는 콘솔이 먼저 실행되어서 "constructor로 생성" 의 문구를 출력하였고, 다음에는 render 함수가 실행되었다. 그리고 렌더링이 된 후, componentDidMount 함수가 실행되는 것을 볼 수 있다.

이것을 위의 그림의 가장 왼쪽에 있는 박스이다. 생성될때 이런 주기로 생성이 된다. 그러면 update는 무엇일까 ? on/off 버튼을 누르면 무슨 일이 나타나는지 보자

버튼을 누르닌까, render함수가 실행되고 componentDidUpdate 함수가 실행되었다.

위의 그림에서 3가지로 상태를 변화 시키는 방법이 있는데 나는 그 중에서 setState를 사용하였다. 공식문서에서 state를 변경시킬때는 setState를 사용하라고 한다. 직접적으로 바꾸지말고. 그 이유가 이 Lifecycle과 관련이 있기 때문이다.

간략하게 다시 적으면,

  1. componentDidMount : 컴포넌트가 DOM에 렌더링 된 후에 실행된다.
  2. componentDidUpdate : 컴포넌트가 DOM에 렌더링 된 후에 새로 업데이트 된것을 실행된다.
  3. componentWillUnmount : 컴포넌트가 지워지기 전에 실행된다.

위와 같은 메소드를 “생명주기 메소드” 라고 부른다.

setState 사용하기

: 공식문서에서 직접 State를 수정하지 말라고 말한다.
예를 들어 this.state.comment = 'Hello'; 이렇게 직접적으로 바꾸게 되면, 컴포넌트를 다시 render하지 않기 때문이다.

그렇게 때문에 우리는 setState를 사용하고,

this.setState({comment: 'Hello'});

라고 적어주어야한다.
this.state를 지정할 수 있는 유일한 공간은 constructor다.

profile
UX를 개선하는것을 즐기고 새로운것을 배우는것을 좋아하는 개발자입니다.

0개의 댓글