16일차 - 클래스형 컴포넌트와 함수형 컴포넌트의 생명주기

류연찬·2022년 11월 16일
0

Codecamp FE07

목록 보기
16/39

Class

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



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

클래스에서 함수와 변수를 사용할때는 function, let, const를 붙이지 않습니다.

class {
  // class에서의 함수 작성
  sayHi() {
    console.log("안녕하세요")
  }

  // class에서의 변수 작성
  sayHi = "안녕하세요"
}

클래스에서 만들어진 함수를 메소드라고 부릅니다.

클래스에서 상속

클래서에서는 공통 기능extends를 통해 상속해줄 수 있습니다.

//지상 몬스터와 공중 몬스터 만들기
 
// 공통 기능
basicFunc {
	hp = 100
	attack() {
		console.log("공격을 시도했습니다.")
	}
}

// 지상몬스터의 피하기
groundMonster extends basicFunc {
	 avoid() {
		console.log("지상에서 뛰어서 피했습니다.")
	}
}

// 공중몬스터의 피하기
flyMonster extends basicFunc {
	avoid() {
		console.log("공중으로 날아 피했습니다.")
	}
}

class component 예제

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 +1 // this.state.count == prev.count
	  }))
	}

	// 화면 그리는 부분
	render() {
      return (
        <div> 
          // this는 class 자기자신을 뜻합니다.
          <div>현재 카운트 : {this.state.count}</div>

          // 직접 바인딩 하실때는 onClick={this.onClickCounter.bind(this)} 라고 적어주셔야 합니다.
          <button onClick={this.onClickCounter}>카운트 올리기</button>
        </div>
      )
	}
}

this 바인딩(.bind(this))

this는 어디서 실행하냐에 따라서 변화하는 이슈가 있습니다. 즉, 실행하는 주체에 따라서 this가 다르게 나옵니다.
이렇게 바뀌는 this를 동적 this라고 합니다.
따라서 onClickCounter 를 클릭시에 this가 onClickCounter로 바뀌게 됩니다.
변화하는 this를 class로 고정하기 위해서는 this를 바인딩해주시거나 화살표 함수를 써줘야합니다.
이렇게 바인딩 과정을 거쳐서 고정된 this를 렉시컬 this라고 합니다.

class component의 생명주기

컴포넌트의 생명주기는 컴포넌트가 브라우저에 나타나고 업데이트 되고, 사라지게 될 때 호출되는 메서드 입니다.
쉽게 말해, 특정 시점에 코드가 실행되도록 설정할 수 있다는 것입니다.
메서드에 대해 간략히 요약한다면,

  • 그리기 → render
  • 그리고 난 뒤 → componentDidMount
  • 그리고 난 뒤 변경 → componentDidUpdate
  • 그리고 난 뒤 사라짐 → componentWillUnmount

class component 생명주기 예제

import { component } from 'react'

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

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

  // 화면 그리는 부분
  render() {
    return (
      <div> 
        // this는 class 자기자신을 뜻합니다.
        <div>현재 카운트 : {this.state.count}</div>

        // 직접 바인딩 하실때는 onClick={this.onClickCouter.bind(this)} 라고 적어주어야 합니다
        <button onClick={this.onClickCouter}>카운트 올리기</button>
      </div>
    )
  }
}

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

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

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



Ref

React를 사요하기 전까지 특정 태그에 접근할 때 document.getElementById() 를 사용했습니다.
하지만 React는 실제 DOM이 아닌 virtual DOM(가상돔)을 다루기 때문에 위의 방법으로 접근했을 때 문제가 생길 수 있습니다.
따라서 Ref 를 이용해 태그를 직접 변수에 저장하도록 하겠습니다.

클래스형 컴포넌트 createRef()

class형 컴포넌트에는 createRef() 메서드를 이용해 특정 태그에 접근합니다.

import {createRef} from 'react'

// Ref코드 생성
inputRef = createRef()

// Ref를 적용하고싶은 input태그(=접근하고싶은 태그)
<input type="text" ref={this.inputRef} />

// 태그에 접근해서 실행시킬 함수
componentDidMout(){
  console.log("마운트 됨")
  this.inputRef.current?.focus()
}

함수형 컴포넌트 useRef()

함수형 컴포넌트에서는 useRef() 훅은 이용해 특정 태그에 접근합니다.

import {useRef} from 'react'

// Ref코드 생성
const inputRef = useRef()

// Ref를 적용하고 싶은 input태그(=접근하고 싶은 태그)
<input type="text" ref={inputRef}/>

// 태그에 접근해서 실행시킬 함수
useEffect(() => {
  console.log("마운트 됨")
  inputRef.current?.focus()
})

🔔 React는 SPA(Single Page App) 구조입니다.
SPA는 하나의 페이지를 가지는 구조로, virtual DOM으로 여러 컴포넌트를 만들고 필요할 컴포넌트를 조합하고 조합된 컴포넌트를 진짜 돔에 얹어서 보여줍니다.


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

클래스형 컴포넌트에는 componentDidMount 와 같은 생명주기 메서드들이 있습니다.
그리고 함수형 컴포넌트에서 생명주기와 관련된 훅이 있습니다. 바로 useEffect 입니다.

useEffect

componentDidMount

// 의존성 배열[]에 아무것도 넣지 않으면 Mount시에만 렌더해주고 끝나게 됩니다.(1번만 실행)
useEffect(() => {
  console.log("마운트 됨!!")
}, [])

componentDidUpdate

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


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

componentWillUnmount

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

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

useEffect의 실행 지점
생명주기 메서드, 훅은 기본적으로 render 이후에 실행됩니다.
따라서 useEffect와 lifecycle 메서드는 render 이후에 실행됩니다.


useEffect 사용시 주의사항

useEffect 안에서 setState 를 사용할때는 정말 필요한 경우가 아니라면 지양하는게 좋습니다.

컴포넌트가 마운트된 이후에 setState 를 적용하게 되면,
1. state가 변경되고
2. 변경된 state로 컴포넌트가 다시 그려지게(re-render) 됩니다.

즉, useEffect 내에서 setState 를 사용하게 되면 불필요한 리렌더나 무한루트를 일으키게 되고 성능면에서 비효율적이게 됩니다.

0개의 댓글