1-7. React Lifecycle 제어하기 - useEffect

밥이·2022년 2월 22일
0

React Project

목록 보기
7/14

React Lifecycle(생애주기) 제어하기 - useEffect

리액트 컴포넌트도 이런 생명주기 LifeCycle을 갖는다.

위 사진은 리액트 컴포넌트의 LifeCycle이다.

리액트의 생애주기를 간단하게 설명하자면 탄생 -> 변화 -> 죽음 이 세가지 단계에 대한 이야기일 뿐이다.

탄생(Mount) : 컴포넌트가 화면에 나타나는 것
변화(Update) : State가 바뀌거나 부모가 리렌더 될때
죽음(UnMount) : 컴포넌트가 화면에서 사라질때
(이렇게 3가지 메소드가 있음)

그럼 이런 LifeCycle(생애주기)를 제어한다는건 우리에게 어떤 의미가 있을까?
이렇게 컴포넌트가 탄생하고, 변화하고, 사라지고 죽는 순간에 우리가 각각 어떤 작업을 수행 시킬 수 있다는 것을 우리는 LifeCycle을 제어한다. 또는 이용한다 라고 얘기함.

예를 들어 탄생 시에는 초기화 작업을 시킨다던가,
또는 변화가 일어날때는 해당 변화를 통해 발생할 수 있는 예외에 대한 처리작업을 추가로 수행 해준다던가.
또는 컴포넌트가 사라지게 될 때, 해당 컴포넌트가 사용하던 메모리를 반환하게 하는 그런 작업하게 하는 것임.

리액트를 포함해서 소프트웨어를 더욱 견고하고 효율적으로 개발할려면 자신이 사용하는 기술에 LifeCycle을 온전히 이해하고 이용할 수 있어야함.

원래 state같은 기능들은 class형 컴포넌트만 이용할 수 있고, 함수형 컴포넌트는 못씀, 그런데 우린 useState()를 이용해 함수형으로 만들어 잘 관리를 해왔음,
그런게 이렇게 React Hooks라는게 개발 되면서, use키워드를 붙여가지고, 함수처럼 사용할 수 있게된것임

React Hooks라는건 함수형 컴포넌트에서 class컴포넌트형 기능을 낚아채듯이 훔쳐와서 사용할 수 있도록 도와주는 기능을 얘기함.

그럼 그냥 class형 컴포넌트 사용하면 되지, 왜?? React Hooks 기능을 사용하면서 까지 함수형 컴포넌트를 굳이 왜 쓰고 있을까??

class형 컴포넌트에는 고질적인 문제가 하나 있음,
함수형 컴포넌트보다 같은 기능을 구현하는데에 비교적으로 굉장히 많은 코드를 써야하고, 치명적인 단점은 중복코드를 굉장히 많이 써야하는 그런 단점이 있음.

useEffect 사용법

2개의 파라미터를 전달하는데.
첫번째 파라미터는 콜백함수를 전달함
두번째 파라미터는 [ ] Depcy(의존성배열)을 전달해줘야함.

[ ] Depcy안에 들어있는 값중 하나라도 변화하면, 첫번째 파라미터인 콜백함수가 실행이됨.
즉, [ ] 이 배열에 자꾸 변화하는 어떤 값을 넣으면, 콜백함수가 값이 변화할때 마다 계속 수행이됨.

Unmount를 만들려면 useEffect() 콜백함수 안에 함수를 하나 리턴해주면됨
그럼 이 return된 함수는 Unmount(사라지는) 시점에 실행됨.

Lifecycle.js

import { useEffect, useState } from 'react';

const Lifecycle = () => {

const [cnt, setCnt] = useState(0);
const [txt, setTxt] = useState('');
const [isVisible, setIsVisible] = useState(false);
const toggle = () => {
	setIsVisible(!isVisible)
}

// 탄생
// 의존성배열에 빈배열을 넣으면 딱 한번만 실행함
useEffect(() => {
	console.log('Mount!')
}, [])

// 변화
// state를 변경시키는 순간에 useEffect로 제어하기
// Deps배열을 전달하지 않으면됨, 모든 값이 업뎃 될때마다 실행됨
useEffect(() => {
	console.log('Update!')
})

// Deps배열에 값을 전달하고, 그 값이 업뎃하면 그 순간 콜백함수 실행
// 우리가 감지하고 싶은 값만 감지해서, 그 값이 변하는 순간에만 실행
useEffect(() => {
	console.log(`cnt update : ${cnt}`)
	if (cnt > 5) {
		alert('count가 5를 넘었습니다. 따라서 1로 초기화합니다.');
		setCnt(1);
	}
}, [cnt])

useEffect(() => {
	console.log(`txt update : ${txt}`)
}, [txt])


// 죽음


return (<div style={{ padding: 20 }}>
	<p>Lifecycle 실험하기</p>
	<div>
		{cnt}
		<button onClick={() => { setCnt(cnt + 1) }}>증가</button>
	</div>

	<div>
		<input value={txt} onChange={(e) => { setTxt(e.target.value) }} />
	</div>

	<div>
		<button onClick={toggle}>ON/OFF</button>
		{isVisible && <UnmountTest />}
		{/* 단락회로 평가 사용하기  && 연산자 (모두가 참일때 true반환)
		isVisible값이 true면 컴포넌트를 반환하여 화면에 보여주고
		만약 false면, isVisible값은 이미 false이기 떄문에 컴포넌트도 렌더링 안됨
		*/}
	</div>

</div >)
}

// isVisible스테이트가 True일떄만 이 컴포넌트를 보여줌
const UnmountTest = () => {

// 컴포넌트가 죽는순간(Unmount) 제어하기
useEffect(() => {
	console.log('Mount!!!!! 탄생 !!');

	// Unmount는 어떻게 만드냐면, 콜백함수가 함수를 하나 리턴하게 하면됨

	return () => {
		// 그럼 이 return된 함수는 Unmount(사라지는) 시점에 실행되게된다.
		console.log('UnMount 죽음 ㅠㅠ');
	}
}, [])
return <div>Unmount Testing Component</div>
}

export default Lifecycle;

0개의 댓글