가변적인 상태를 가지는 state 변수를 선언하는 Hook
일반적으로 구조 분해 할당을 사용하여 표현함
import { useState } from "react";
const [변수명, set변수명] = useState(초기값);
// 변수명 : 현재 state
// set변수명 : 현재 state를 다른 값으로 업데이트하고 리렌더링 할 수 있는 set 함수
setState(number + 1);
setState(number => number + 1);
동일한 set 함수를 여러 번 수행했을 때의 결과가 다르다.
const [number, setNumber] = useState(0);
// 일반 업데이트
<button onClick={() => {
setNumber(number + 1);
setNumber(number + 1);
setNumber(number + 1);
}}>일반 +3</button>
// 함수형 업데이트
<button onClick={() => {
setNumber((number) => number + 1);
setNumber((number) => number + 1);
setNumber((number) => number + 1);
}}>함수형 +3</button>
// 최종 결과: 일반(0 -> 1) vs 함수형(0 -> 3)
React는 렌더링의 횟수에 따라 성능이 좌우된다.
따라서, React는 성능을 최적화하기 위해 자체적으로 이벤트 핸들러의 모든 코드가 실행된 이후에 state를 업데이트한다.
따라서, 이벤트 핸들러가 완전히 실행될 때까지 핸들러 내부의 state 값은 이전 state 값으로 고정되어 있다.
일반 업데이트는 계속해서 기존에 고정된 number에 단순히 1만 추가하라는 행위만 반복하고 있다.
반면, 함수형 업데이트는 함수들을 큐(queue) 에 넣어 수행하기 때문에, 이전 함수의 결과값을 다음 함수의 입력값으로 사용할 수 있다.
React 컴포넌트가 (리)렌더링될 때마다 특정 작업을 수행하는 Hook
import { useEffect } from "react";
useEffect(수행할 함수, 의존성 배열)
(리)렌더링될 때마다 특정 작업을 수행하게 할 컴포넌트를 bind한다.
import { useEffect, useState } from "react";
function App() {
const [value, setValue] = useState("");
const valueChangeHandler = (event) => {
setValue(event.target.value);
};
useEffect(() => {
console.log("해당 컴포넌트이 (리)렌더링 될 때만 반응함");
}, [value]); // value가 (리)렌더링 될 때만 반응함
return <input type="text" value={value} onChange={valueChangeHandler} />;
}
빈 배열([]
)을 입력할 경우, 처음 렌더링된 이후 어떠한 렌더링에도 수행되지 않는다.
useEffect(() => {
console.log("첫 렌더링 이후 어떠한 (리)렌더링에도 반응하지 않음");
}, []);
컴포넌트가 DOM에서 제거되기 직전에 실행되는 작업
useEffect()의 함수 내부에 return문을 사용하고 그 안에 실행할 작업을 작성한다.
useEffect(() => {
console.log("value 컴포넌트가 (리)렌더링될 때마다 수행함");
return () => {
console.log("value 컴포넌트가 DOM에서 제거되었습니다.");
};
}, [value]);
렌더링에 관여하지 않는 값을 참조하는 Hook
import { useRef } from "react";
const 변수명 = useRef(초기값);
// 초기값 : 첫 렌더링에만 적용되며, 이후 해당 값을 변경하는 경우, 변경한 값이 적용됨
ref = {current: 초기값}
주로 DOM 요소를 선택할 때 사용함
function App() {
const valueRef = useRef("");
return <input type="text" ref={valueRef} />
}
기본 개념
useState : 렌더링에 반영되는 값에 사용한다.
useRef : 렌더링에 반영되지 않는 값에 사용한다.
<input>
과의 관계코드
출력 결과
<input>
에 어떤 Hook을 쓰는 것이 더 효율적인가?나는 useState를 사용하는 것이 더 효율적이라고 생각한다.
<input>
으로 접근했을 때 가장 먼저 생각난 것은 검색창 이었다.
검색창은 <input>
창에 글자를 입력할 때마다 일치하는 연관 검색어를 추천해준다.
해당 컴포넌트에는 useState를 사용하는 것이 적합하다.
useRef를 사용해서도 검색 기능을 수행할 수는 있지만, 화면에 보여지지 않고 내부적으로 검색어를 파악한 뒤 검색 결과를 출력해야 하며, 이는 UX 적인 부분에서 useState 보다 좋지 않다고 생각한다.