2023. 4. 3

Junghan Lee·2023년 4월 3일
0

TIL Diary

목록 보기
30/52

INDEX

CLASS(.bind(this))
Class 컴포넌트의 생명 주기(life cycle)
함수형 컴포넌트의 life Cycle
useEffect(componentDidMount, componentDidUpdate, componentWillUnmount)
open-API


intro

class를 통해 함수를 그룹핑해서 사용하는 방식 -> 객체지향프로그래밍-OOP
class안의 함수는 function붙이지 않는다!!!

Class?

객체이자 물건을 만드는 설명서
class안에는 함수와 변수를 넣을 수 있고 이 함수와 변수를 조합해 붕어빵과 몬스터를 만드는 방법을 적어둘 수 있다. 이를 만들고 싶다면 new 붕어빵() 으로 만들어준다.
만들어진 붕어빵과 몬스터는 객체 혹은 인스턴스 라고 부른다.

클래스에서의 함수와 변수 사용법

class Monster {
  // class의 변수 작성
  power = 50;
  
  // class의 함수(메소드) 작성
  attack(): void {
    console.log("공격합니다!!");
  }
}

클래스에서 만들어진 함수 = 메소드

클래스에서의 상속
클래스에서는 공통 기능을 extends를 통해 상속해줄 수 있다.

class Monster {
  power = 50;
  attack(): void {
    console.log("공격합니다!!");
  }
}

// 클래스 상속 : 기존 클래스에 기능을 추가해서 만든 클래스
class SuperMonster extends Monster {
  run(): void {
    console.log("도망가자!!");
  }

  // 오버라이딩: Monster의 메소드를 다시 정의해서 덮어씌운다.
  attack(): void {
    console.log("슈퍼 몬스터 필살기!!");
  }
}

const monster = new Monster();
console.log(monster.power); // 50
monster.attack(); // 공격합니다!!

const supermonster = new SuperMonster();
console.log(supermonster.power); // 50
supermonster.attack(); // 슈퍼 몬스터 필살기!!

class component 만들어보기

//count 컴포넌트를 만들어보겠습니다.
import {component} from 'react'

export default class ClassCounterPage extends Component {
	// class 변수의 선언 방식
	state = {
				count : 0,
			}

	// class에서의 함수 사용방식 
		onClickCounter = () =>{
				console.log(this.state.conut)
				this.setState(((prev))=>({
						count : this.state.count(=prev.count) +1
			}))
		}

	// 화면 그리는 부분
	render(){
		return(
			<div> 
				{/* this는 class 자기자신을 뜻합니다. */}
					<div>현재 카운트 : {this.state.count}</div>
				{/* 직접 바인딩할 때는 onClick={this.onClickCouter.bind(this)} 라고 적어주셔야 합니다. */}
					<button onClick={this.onClickCouter}>카운트 올리기</button>
			</div>
			)
		}
	}

this 바인딩( .bind(this))
this는 어디서 실행하냐에 따라서 변화하는 이슈가 있다. 즉, 실행하는 주체에 따라 this가 다 다르게 나오며 이렇게 바뀌는 this는 동적 this라고 한다.
따라서 onClickCounter를 클릭하면 this가 onClickCounter로 바뀌게 된다.
변화하는 this를 class로 고정하려면 this를 바인딩해주거나 화살표 함수를 써야 한다. 이렇게 바인딩 과정을 거쳐 고정된 this는 렉시컬 this 라고 한다.

class컴포넌트의 생명 주기(Life Cycle)

컴포넌트의 생명주기는 컴포넌트가 브라우저에 나타나고 업데이트되고, 사라지게 될 때 호출되는 메서드로 특정 시점에 코드가 실행되도록 설정할 수 있다는 것이다.
이에 대해 간략히 요약하면
1) 그리기->render 인풋창 그리기
2) 그리고 나서 componentDidMount(포커스 깜빡 처리는 여기서)
3) 그리고 난 뒤 변경됐을 때 -> componentDidUpdate
4) 그리고 난 뒤 사라질 때 -> componentWillUnmount (다하고 사라져줘)

// class 컴포넌트의 생명주기
import {Component} from 'react'
import Router from 'react'


export default class ClassCounterPage  extends Component{
		state = {
					count : 0,
				}


//lifecycle 메서드
componentDidMount(){
		console.log(" Mount됨")
		//input태그 선택해서 포커스 깜빡거리게 하기
	}
componentDidUpdate(){
		console.log("수정하고 다시 그림!!")
	}
componentWillUnmount(){
		console.log("여기서 나갈래요")
		//나가기 전에 마지막으로 할 것들
	}


// 카운트 올리기 함수
onClickCouter = ()=>{
		console.log(this.state.conut)
		this.setState(((prev))=>({
		count : this.state.count(=prev.count) +1
			}))
	}

// 현재 페이지 나가기 함수 _ componentWillUnmount를 보기위한
onClickMove = () => {
		router.push('/')
	}
// 화면 그리는 부분
render(){
	return(
		<div> 
			// this는 class 자기자신을 뜻합니다.
				<div>현재 카운트 : {this.state.count}</div>
	
			// 직접 바인딩 하실때는 onClick={this.onClickCouter.bind(this)} 라고 적어주셔야 합니다.
				<button onClick={this.onClickCouter}>카운트 올리기</button>
				<button onClick={this.onClickMove}>나가기</button>
		</div>
		)
	}
}

페이지가 그려진 후 componentDidMount를 통해 console.log를 확인할 수 있고

카운트를 올려준 후, componentDidUpdate를 통해 수정된 사실을 알 수 있다.

페이지 이동하기를 통해 componentDidUnmount가 실행되는 것을 확인할 수 있다.

실시간 채팅방 접속자, 나간 사람 등을 백엔드에 알려주는 데 쓰임(누군가 나가고 들어옴을 알려준다.) 어떻게 나가든지 componentWillUnmount에 나가기 api 요청하면 뭘 클릭해서 페이지를 벗어나든 페이지가 이동되기 전에 실행되고 페이지가 이동됨

함수형 컴포넌트의 생명주기 훅 useEffect

클래스형 컴포넌트에 componentDidMount같은 생명주기 메서드들이 있는 반면 함수형 컴포넌트에서는 어떻게 사용할까? -> useEffect

useEffect
1) componentDidMount

// 의존성 배열[]에 아무것도 넣지 않으면 Mount시에만 렌더해주고 끝나게 됩니다.(1번만 실행)

useEffect(()=>{
		console.log("마운트 됨!!")
	},[])

2)componentDidUpdate와 비슷한

// 의존성 배열이 없기 때문에 뭐 하나라도 바뀌면 무조건 다시 실행됩니다.
useEffect(()=>{
		console.log("수정하고 다시 그려짐!!")
	})


// someState가 수정될때만 리렌더 해주기
useEffect(()=>{
		console.log("수정하고 다시 그려짐!!")
	},[someState])

3)componentWillUnmount

useEffect(()=>{
		console.log("수정하고 다시 그려짐!!")

		//이부분이 끝나고 진행할 것들
		return(()=>{
			console.log("여기서 나갈래요!!")
		})

	})

참고) 의존성 배열[], 중요한가? O
깜빡하고 useEffect에 의존성 배열을 적어주지 않고 리턴도 해주지 않는다면 무한렌더링이 된다. 또한 useEffect는 의존성 배열 인자에 따라 렌더가 달라지므로 의존성 배열을 잘 의존성 배열이 함수형 컴포넌트의 생명주기를 결정하는 포인트 !

useEffect의 실행 시점 -> 생명주기 메서드, 훅은 기본적으로 렌더(화면그리기) 이후에 실행되므로 useEffect와 lifecycle 메서드는 렌더링 이후에 실행된다.

useEffect 사용시 주의 사항

useEffect안에서 setState의 사용은 정말 필요한 경우가 아니라면 지양할 것
-> 컴포넌트가 마운트된 이후에 setState 적용하게 되면
1) state가 변경되고
2) 변경된 state로 컴포넌트가 다시 그려지게 된다.(리렌더)

즉, useEffect 내에서 setState 사용시 불필요한 리렌더나 무한루프가 일어나 성능적으로 비효율적이다.

open API

오픈 API는 누구나 사용할 수 있도록 공개된 API로 예를 들면 동물 이미지, 날씨 정보, 바이러스 정보, 금융 정보 등을 API를 통해 무료로 데이터를 사용할 수 있다. 이를 잘 활용하면 백엔드 없이도 서비스를 만들 수 있다.
https://github.com/public-apis/public-apis
구글) public API 검색

useEffect& Open API
브라우저가 실행하자마자 요청을 하도록 useEffect 사용

axios 사용하기 위해서는 설치하고 import 해야함
useEffect안에는 async 붙일 수 없어서 useEffect안에 함수를 선언하고 함수를 실행해야 함

HTTPS / HTTP

import { useEffect, useState } from "react";
import axios from "axios";

export default function RestGetPage(): JSX.Element {
  const [img, setImg] = useState("");

  useEffect(() => {
    // async를 붙이기 위해 함수를 선언하고, 만든 함수를 실행시켜야 합니다.
    const getImg = async (): Promise<void> => {
      const result = await axios.get("https://dog.ceo/api/breeds/image/random");
      setImg(result.data.message);
    };
    void getImg();
  }, []);

  return <img src={img} />;
}

요즘은 axios 쓰지 않고 reactQuery 쓴다. (useQuery는 graphql // apolloClient) 장점 : 캐싱 (axios는 받아왔다고 global state로 저장 못함 : 캐싱이 안됨)

브라우저가 실행되자 마자 실행하려면 useEffect를 사용하지 않고 그냥 적어줘도 되나?
가능하지만 리렌더면에서 비효율적( 계속 실행됨 )

리렌더의 조건에는 state의 변화가 있으므로 컴포넌트의 state가 변할 때마다 다시 렌더하게 된다.

불필요한 리렌더는 반드시 제거해야 한다

profile
Strive for greatness

0개의 댓글