210129 TIL #React#Typescript

이예주·2021년 1월 29일
0

Today I Learned

목록 보기
6/10

React

웹 게임을 만들며 배우는 React(6)

리액트 라이프사이클

첫번째 렌더링이 성공적으로 실행되었다면 componentDidMount 함수가 실행된다. setState 등의 이유로 리렌더링을 할 때에는 실행되지 않는다. 이것과 반대로 componentWillUnmount는 컴포넌트가 제거되기 직전에 실행되는 함수이다. componentDidUpdate는 리렌더링 후에 실행되는 함수이다.

이렇게 첫 컴포넌트의 렌더링 후, 리렌더링 후, 제거 직전에 실행되는 함수들을 통틀어 라이프사이클이라 부른다. 클래스의 라이프사이클은 다음과 같다.

constructor → render → ref → componentDidMount → (setState/props 변화 → shouldComponentUpdate(true) → render → componentDidUpdate) → 컴포넌트 제거(부모 컴포넌트) → componentWillUnmount → 소멸

componentDidMount에서는 주로 비동기 요청을 많이 한다. 반대로 componentWillUnmount에서는 비동기 요청 정리를 많이 한다.

componentDidMount() {
  this.interval = setInterval(() => {
    console.log('interval');
  }, 1000);
};

첫 렌더링이 된 직후, setInterval과 같은 비동기 요청을 해줄 경우, 컴포넌트가 제거될 때 이 요청을 따로 제거해주지 않으면 웹사이트가 종료될 때까지 비동기 요청이 계속되는 문제가 있다. 비동기 요청이 계속되면 메모리 또한 끝없이 할당되어서 큰 문제가 될 수 있다. 이때 componentWillUnmount로 비동기 요청을 정리하는 것이다.

componentWillUnmount() {
  clearInterval(this.interval);
};

클래스의 경우 componentDidMountcomponentDidUpdate에서 모든 state를 조건문으로 분기 처리한다.

고차함수

렌더 내부에서 onClick과 같은 메서드에 함수 자체를 넣는 건 성능 최적화에 문제가 발생할 수 있으므로 따로 빼주는 것이 좋다. onClick 내부에서 바로 this로 함수를 불러오게 하려면 () =>를 해당 함수에 다시 넣어주어야 한다.

/* 수정 전 */
onClickBtn = (choice) => {};
<button id="rock" className="btn" onClick={() => this.onClickBtn('바위')}>바위</button>

/* 수정 후 */
onClickBtn = (choice) => () => {};
<button id="rock" className="btn" onClick={this.onClickBtn('바위')}>바위</button>

이와 같이 함수를 연달아 쓰는 패턴을 고차 함수라 한다.


✓주의: setState를 연달아 사용하는 경우는 리액트가 알아서 한 번에 렌더링을 해준다.

훅스 useEffect

훅스에는 componentDidMount, componentDidUpdate, componentWillUnmount 등과 같이 라이프사이클을 지원해주는 함수가 없다. 대신 사용하는 함수가 바로 useEffect이다. useEffect는 따로 함수처럼 만들어 사용한다.

useEffect(() => {
  interval.current = setInterval(chagneHand, 100);
  return () => {
    clearInterval(interval.current);
  }
}, [imgCoord]);

훅스의 useEffect는 클래스의 라이프사이클 함수 세 개의 기능을 한 번에 담고 있기 때문에 아무래도 사용하기가 클래스보다 복잡한데, useEffect의 함수 내부는 componentDidMountcomponentDidUpdate의 역할을 하고, return 내부는 componentWillUnmount 역할을 한다. useEffect의 두번째 인수는 배열인데, 이 배열에 넣은 값들이 바뀔 때마다 useEffect가 실행된다. 위의 코드에서는 imgCoord가 바뀔 때마다 setInterval이 실행되어야 하므로 배열 값에 imgCoord가 들어간다.

배열 값에 여러 개의 state가 들어가도 되지만, 함수 내부에서 변화가 일어나는 state만 배열 값에 넣어주는 것이 좋다. useEffect는 여러 번 사용이 가능하므로 여러 개의 state를 관리할 때에는 useEffect를 따로 분리해주는 것이 좋다.

useEffect의 특징은 렌더링이 될 때마다 실행과 종료를 반복한다는 것이다. 즉, 렌더링을 하면 setInterval이 실행되고, 후에clearInterval도 실행된다.

✓주의: useLayoutEffect는 리사이징과 같은 화면의 레이아웃의 변화를 감지할 때 사용된다. 즉, 화면의 레이아웃이 바뀌기 전에 실행된다.

클래스와 훅스의 라이프사이클 차이점

클래스의 라이프사이클은 해당 함수마다 모든 state들을 관리할 수 있는 반면에, 훅스의 useEffect는 state 별로 함수를 실행한다고 생각하면 된다. 물론 인자의 배열 값에 여러 state를 넣어도 되지만, state의 값이 변할 때마다 useEffect가 실행되므로 차라리 따로 분리해주는 편이 좋다.

Typescript

타입스크립트 입문 - 기초부터 실전까지(3)

interface

인터페이스는 상호 간의 약속이라고 생각하면 쉽다. 변수나 함수를 정의할 때 인터페이스를 사용하면 해당 변수나 함수를 어떻게 사용해야하는지의 가이드가 되어준다. 라이브러리를 직접 만들거나 여러 명이서 동시에 협업을 할 때 미리 정의할 수 있으므로 자주 사용된다.

인터페이스를 활용하는 곳은 변수, 함수 뿐만이 아니라 함수 스택(구조), 인덱싱, 딕셔너리, 상속 등도 있다.

유료 강좌이기 때문에 코드는 생략!

Type Aliases

타입 별칭은 특정 타입이나 인터페이스를 참조할 수 있는 타입 변수를 의미한다. 어느 곳에서나 사용 가능하다.

/* string 타입을 사용할 때 */
const name: string = 'capt';

/* 타입 별칭을 사용할 때 */
type MyName = string;
const name: MyName = 'capt';

인터페이스와 타입 별칭의 차이점

타입 별칭은 새로운 타입 값을 하나 생성하는 것이 아니라 정의한 타입에 대해 나중에 쉽게 참고할 수 있게 이름을 부여하는 것이다.

/* 인터페이스 */
interface Developer {
  name: string;
  skill: string;
}

let capt: Developer;

/* 타입 별칭 */
type Developer = {
  name: string;
  skill: string;
}

let thor: Developer;

VSCode에서 인터페이스와 타입의 프리뷰를 확인해 보면 차이점을 확인할 수 있다. 위의 코드에서 capt 변수의 타입을 정의했을 때의 프리뷰는 해당 인터페이스를 가리키고 있다. 반대로 thor 변수의 타입을 정의했을 때의 프리뷰는 해당 타입의 별칭을 모두 보여준다.

가장 큰 차이점은 인터페이스와 달리 타입은 확장이 불가능하다는 것이다. 그렇기 때문에 가능한 한 type보다는 interface로 선언해서 사용하는 것이 좋다.

profile
🏫Chung-Ang Univ. 👩‍💻Computer Science

0개의 댓글