hook에 관해서 공부한 내용
추가할것 :
커스텀 훅은 다른 글에서
요약하자면 Hook은 함수형 컴포넌트가 클래스형 컴포넌트의 기능을 사용할 수 있도록 해주는 기능이다.
hook을 사용해 함수형 컴포넌트에서도 state와 생명주기를 다룰 수 있기에 클래스형 컴포넌트에서만 가능하던 상태관리를 더 손쉽게 할 수 있어 필요하다.
함수형 컴포넌트들은 기본적으로 리렌더링이 될때, 함수 안에 작성된 모든 코드가 다시 실행됨
- 클래스형 컴포넌트들은 method의 개념이므로, 리렌더링이 되더라도 render() 를 제외한 나머지 method 및 state는 그대로 보존이 되어 있음.
이는 함수형 컴포넌트들이 기존에 가지고 있던 상태(state)를 전혀 관리(기억)할 수 없게 만듦
- 그래서 함수형 컴포넌트를 Stateless Component 라고 했던 것.
- 단순하게 React에서의 state 만을 의미하는 것이 아닌, 함수내에 써져 있는 모든 코드 및 변수를 기억할 수 없다는 의미
⇒ 함수형 컴포넌트가 리렌더링될때 무조건 새롭게 선언 & 초기화 & 메모리에 할당이 됨
하지만 Hook의 등장으로, 브라우저에 메모리를 할당 함으로써, 함수형 컴포넌트가 상태(state)를 가질 수 있게 한 것.
⇒ 쉽게 말해서 함수 내에 써져 있는 코드 및 변수를 기억할 수 있게 됐다 라는 의미
공식홈페이지에 따르면 Hook을 만든 이유는 다음과 같다.
1) 컴포넌트 사이에서 상태 로직 재사용의 어려움 -> render props, HOC 등
2) 복잡한 (클래스형) 컴포넌트들은 이해하기 어려움 -> 각종 생명주기 함수들
3) 클래스자체 개념을 이해하기 어려움 -> this 등
Hook은 브라우저의 메모리 자원을 사용하기에 함부로 남발하면 오히려 성능저하를 불러올 수있다. Hook의 성능 최적화 방법은 후에 공부할 예정
Hook에는 규칙이 있다. 이를 꼭 지켜야 정상적으로 hook이 실행되고 코드가 꼬이지 않는다.
eslint-plugin-react-hooks (ESLint 플러그인) 을 사용한다면 아래 두 규칙을 강제한다. (CRA에 포함)
function Form() {
// 1. name이라는 state 변수를 사용하세요.
const [name, setName] = useState('Mary');
// 2. Effect를 사용해 폼 데이터를 저장하세요.
useEffect(function persistForm() {
localStorage.setItem('formData', name);
});
// 3. surname이라는 state 변수를 사용하세요.
const [surname, setSurname] = useState('Poppins');
// 4. Effect를 사용해서 제목을 업데이트합니다.
useEffect(function updateTitle() {
document.title = name + ' ' + surname;
});
// ...
}
// ------------
// 첫 번째 렌더링
// ------------
useState('Mary') // 1. 'Mary'라는 name state 변수를 선언합니다.
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect를 추가합니다.
useState('Poppins') // 3. 'Poppins'라는 surname state 변수를 선언합니다.
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect를 추가합니다.
// -------------
// 두 번째 렌더링
// -------------
useState('Mary') // 1. name state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(persistForm) // 2. 폼 데이터를 저장하기 위한 effect가 대체됩니다.
useState('Poppins') // 3. surname state 변수를 읽습니다.(인자는 무시됩니다)
useEffect(updateTitle) // 4. 제목을 업데이트하기 위한 effect가 대체됩니다.
// ...
- 컴포넌트가 반드시 필요한 리랜더링만을 진행하는가?
- 랜더링이 발생한다면, property 및 method가 반드시 필요한 것만 재할당 할 수 있게 하는가?
- 위 2가지를 무시할만큼, 랜더링이 자주되는가? ) 따라서 메모리를 할당하면서 위의 2가지를 지키지 않아도 되는가?
기본적으로 클래스형 컴포넌트보다 쉽고 직관적으로 같은 기능을 만들 수 있다.
함수형 컴포넌트로 코드 통일 가능
useEffect로 클래스형 Lifecycle에 흩어져 있는 로직 묶음
Custom Hook을 이용해 손쉽게 로직 재사용 가능함
클래스형 컴포넌트에서 로직을 재사용하기 위해 썼던 HOC나 render-props 같은 패턴이 가져오는 컴포넌트 트리의 불필요한 중첩을 없애줌
커스텀 훅에 관한 자세한 내용은 다음 글 참고
자체적으로 제공하는 기본 Hook, 추가 Hook이 있고
사용자가 만들어서 사용할 수 있는 Custom Hook이 있다.
(추가 정리 필요)
리액트에서 제공하는 hook소개와 성능최적화 방법 추가 작성하기