리액트의 Hook이란?
함수형 컴포넌트 내에서 state와 컴포넌트의 생명주기를 연동할 수 있게 해주는 자바스크립트 함수이다. 클래스 없이 리액트를 사용할 수 있게 해 준다.
Hook 사용 규칙
- 컴포넌트 최상단에서만 호출한다. 반복문, 조건문, 중첩 함수 내에서 호출하지 않는다.
- 리액트 컴포넌트 함수 내에서만 호출해야 한다. 순수 자바스크립트 함수 내에서 호출하지 않는다.
eslint-plugin-react-hooks라는 플러그인을 설치하면 규칙에 맞는지 자동으로 검사해 준다. CRA로 앱을 구성하였다면 해당 플러그인이 이미 포함되어 있다.
useState
컴포넌트 내에서 상태 변수를 관리하는 함수다. 상태 변수와 상태를 갱신하는 함수를 반환하며, useState에 전달된 첫 번째 인자(init)가 초기 상태값이 된다.
const [state, setState] = useState(init);
- 컴포넌트에 상태를 추가
- 이전 상태를 기반으로 상태 업데이트 (객체, 배열도 가능)
- 이전 렌더링의 정보를 저장
하는 등의 역할을 한다. set 함수를 호출하여 상태 변수를 갱신하면 컴포넌트가 리렌더링 되기에 무분별한 사용은 지양해야 한다.
주의점
1. 코드가 실행 중인 경우에 상태 변수를 갱신해도 실행 중인 코드의 상태는 변하지 않는다. 갱신할 값을 활용하고 싶다면 일반 변수에 저장하여 사용할 수 있다.
function handleClick() {
console.log(count); // 0
setCount(count + 1); // Request a re-render with 1
console.log(count); // Still 0!
setTimeout(() => {
console.log(count); // Also 0!
}, 5000);
}
// ✅ Fix
const nextCount = count + 1;
setCount(nextCount);
console.log(count); // 0
console.log(nextCount); // 1
2. 상태 변수를 갱신했을 때, 이전 값과 같다면 컴포넌트는 리렌더링 되지 않는다. 이는 상태 변수에 객체나 배열이 할당되어 있을 때 종종 발생하는 문제이다. spread 연산자로 새 객체를 만들어 해결할 수 있다.
obj.x = 10; // 🚩 Wrong: mutating existing object
setObj(obj); // 🚩 Doesn't do anything
// ✅ Correct: creating a new object
setObj({
...obj,
x: 10
});
3. 무한 리렌더링이 발생하는 경우가 있다.
// 🚩 Wrong: calls the handler during render
return <button onClick={handleClick()}>Click me</button>
// ✅ Correct: passes down the event handler
return <button onClick={handleClick}>Click me</button>
// ✅ Correct: passes down an inline function
return <button onClick={(e) => handleClick(e)}>Click me</button>
4. 상태 변수를 갱신하여 함수를 할당하려고 할 때, 할당이 되는 대신 함수가 호출된다. 이는 리액트가 초기 함수와 갱신할 함수를 모두 호출하고 그 결과를 저장하려고 하기 때문이다. () => 코드를 추가하여 이를 의도에 맞게 수정할 수 있다.
const [fn, setFn] = useState(someFunction);
function handleClick() {
setFn(someOtherFunction);
}
// ✅ Fix
const [fn, setFn] = useState(() => someFunction);
function handleClick() {
setFn(() => someOtherFunction);
}
'[React]' 카테고리의 다른 글
[React] React Hook_useRef (0) | 2023.04.12 |
---|---|
[React] React Hook _ useEffect (0) | 2023.03.21 |
[React] 컴포넌트의 라이프사이클 (Lifecycle) (0) | 2023.03.06 |
[React] React와 Vue (0) | 2023.03.01 |
[React] props와 state (0) | 2023.02.27 |
댓글