2022. 8. 29. 00:01ㆍWIL
벌써 주특기 숙련 주차가 지나고 심화 주차가 시작됐다.
숙련 주차에 학습한 내용 몇 가지를 글로 정리하며 복습해보자.
React Hooks - useState
useState는 가장 기본적인 hook이며, 함수형 컴포넌트에서 가변적인 상태를 가지게 해준다.
const [state, setState] = useState(initialState);
useState의 기본적인 형태는 위 코드처럼 생겼다. 비구조 할당 방식으로 선언하며, useState 함수 안에는 초기값이 들어가며, setState를 이용해서 state 값을 수정할 수 있다. 만약 state가 원시 데이터 타입이 아닌 객체 데이터 타입인 경우 불변성을 유지해줘야 한다.
setState를 사용하는 방식에는 또 다른 방식으로 함수형 업데이트가 있다.
// 일반 업데이트
setState(state + 1);
// 함수형 업데이트
setState((state) => { return state + 1 });
위 코드와 같이 setState에 수정할 값이 아닌 함수를 넣을 수 있다. 그리고 그 함수의 인자에서 현재 state을 가져올 수 있고 실행문에 값을 변경하는 코드를 작성할 수 있다.
두 방식의 차이를 아래 코드에서 알아보자.
// src/App.js
import { useState } from "react";
const App = () => {
const [state, setState] = useState(0);
return (
<div>
<div>{state}</div>
<button
onClick={() => {
setState(state + 1);
setState(state + 1);
setState(state + 1);
}}
>
버튼
</button>
</div>
);
}
export default App;
먼저 일반 업데이트 방식으로 onClick 이벤트로 setState(state + 1)를 세 번 호출했지만 state가 1씩 증가한다.
// src/App.js
import { useState } from "react";
const App = () => {
const [state, setState] = useState(0);
return (
<div>
<div>{number}</div>
<button
onClick={() => {
setState((state) => state + 1);
setState((state) => state + 1);
setState((state) => state + 1);
}}
>
버튼
</button>
</div>
);
}
export default App;
이번에는 함수형 업데이트 방식으로 동일하게 세 번 호출했지만 state가 3씩 증가한다.
일반 업데이트 방식은 버튼을 클릭했을 때 세 개의 setState가 각각 실행되는 것이 아니라 배치(batch)로 처리한다. 즉, onClick 이벤트가 발생했을 때 setState라는 명령을 세 번 내리지만 리액트는 그 명령을 하나로 모아 최종적으로 한 번만 실행을 시킨다. 그래서 setState를 여러번 명령해도 한 번만 실행된다.
반면에 함수형 업데이트 방식은 세 번을 동시에 명령을 내리면, 그 명령을 모아 순차적으로 각각 한 번씩 실행시킨다. 0에 1을 더하고 1에 1을 더하고 2에 1을 더해서 3이라는 결과가 나오는 것이다.
React Hooks - useEffect
useEffect는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 수행하도록 설정할 수 있는 Hook이다. 이는 클래스형 컴포넌트에서 사용하는 라이프사이클(Life cycle) 메서드와 같다. 즉, 어떤 컴포넌트가 렌더링 됐을 때 어떤 함수를 실행하거나, 컴포넌트가 화면에서 사라졌을 때 무언가를 실행하기 위해 사용하는 Hook이다.
// src/App.js
import React, { useEffect } from "react";
const App = () => {
useEffect(() => {
console.log("hello useEffect"); // Mount(컴포넌트가 처음 실행될 때) 이 부분이 실행된다.
});
return <div>useEffect</div>;
}
export default App;
브라우저에서 어떤 컴포넌트가 화면에 렌더링 될 때 useEffect 안에 있는 함수가 실행된다. 이게 useEffect의 핵심이다.
이런 useEffect의 특징에 의해 의도치 않은 동작이 일어날 수 있다.
import React, { useEffect, useState } from "react";
const App = () => {
const [value, setValue] = useState("");
useEffect(() => {
console.log("hello useEffect");
});
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
/>
</div>
);
}
export default App;
value라는 state를 생성해 input과 연결시켰다. 그리고 input 창에 어떤 값을 입력하면 onChange 이벤트 발생 시마다 useEffect가 계속 실행되는 것을 볼 수 있다. setValue가 실행되면서 value 값이 변하면 계속 리렌더링이 발생하기 때문이다.
useEffect에는 의존성 배열이라는 것이 있다. 배열에 값을 넣으면 그 값이 바뀔 때만 useEffect를 실행하는 것이다.
useEffect(() => {
console.log("실행하고 싶은 함수");
}, [의존성 배열])
useEffect의 두 번째 인자에 의존성 배열이 들어간다.
// src/App.js
import React, { useEffect, useState } from "react";
const App = () => {
const [value, setValue] = useState("");
useEffect(() => {
console.log("hello useEffect");
}, []); // 비어있는 의존성 배열
return (
<div>
<input
type="text"
value={value}
onChange={(event) => {
setValue(event.target.value);
}}
/>
</div>
);
}
export default App;
위 코드를 보면 의존성 배열 안에 어떠한 값도 넣지 않았다. useEffect는 의존성 배열 안에 있는 값이 변경될 때 실행되기 때문에 아무런 값도 넣지 않으면 useEffect는 첫 마운트 시 한 번만 실행되고, 그 이후로는 실행되지 않는다.
useEffect에서는 컴포넌트가 나타났을 때 실행되는 이펙트(effect) 함수처럼 컴포넌트가 사라졌을 때 실행하는 클린 업(clean up)이라는 함수가 있다. 이는 클래스형 컴포넌트 라이프사이클 메서드 중 Unmount(컴포넌트 제거) 시 발생하는 componentWillUnmount와 같다.
// src/App.js
import React, { useEffect } from "react";
const App = () => {
useEffect(() => {
// 화면에 컴포넌트가 나타났을(mount) 때 실행하는 부분
return () => {
// 화면에서 컴포넌트가 사라졌을(unmount) 때 실행하는 부분
}
}, [])
return <div>hi, useEffect</div>
};
export default App;
클린 업을 하는 방법은 useEffect 안에서 return을 해주고 이 부분에 실행되길 원하는 함수를 넣으면 된다.
정리하자면
- useEffect는 화면에 컴포넌트가 mount 또는 unmount 됐을 때 실행하고자 하는 함수를 제어하게 해주는 hook이다.
- 의존성 배열을 통해 함수의 실행 조건을 제어할 수 있다.
- useEffect에서 함수를 한 번만 실행시키고자 할 때는 의존성 배열을 빈 배열로 둔다.
'WIL' 카테고리의 다른 글
[Chapter 4] 6주 차 회고 - React & Spring 미니 프로젝트 (0) | 2022.09.11 |
---|---|
[Chapter 3-3] 5주 차 회고 - React 심화 (0) | 2022.09.01 |
[Chapter 3-1] 3주 차 회고 - React 입문 (0) | 2022.08.21 |
[Chapter 2] 2주 차 회고 - 프로그래밍 기초 (0) | 2022.08.14 |
[Chapter 1] 1주 차 회고 - 미니 웹 프로젝트 (0) | 2022.08.07 |