Hook 이해하기
Hook이란?
- 컴포넌트에는 2가지 클래스, 함수 컴포넌트가 존재한다.
Funtion 컴포넌트 | Class 컴포넌트 |
---|---|
state 사용 X | 생성자에서 state 정의 |
Lifecycle에따른 기능 구현 X | setState()를 통해 state 업데이트 |
Hooks | Lifecycle methods 제공 |
- 갈고리처럼 컴포넌트 라이프사이클에 맞추어 원하는 시점에 수행하는 함수를 의미
- 훅은 모드 use로 시작하는 이름을 가져야 한다.
useState()
- 함수 컴포넌트는 state가 없기에 useState()를 통해 state를 사용한다. ```javascript import React, {useState} from “react”;
function Counter(props){ var count = 0; return ( <div> <p>총 {count}번 클릭했습니다.</p> </div> ); }
- 위의 코드는 count라는 변수를 갖고 있다. 하지만 state가 없기에 count 값이 바뀌더라도 컴포넌트가 재랜더링 되지 않아 이것이 돔에 반영되지 않아 화면이 바뀌지 않을 것이다.
```javascript
import React, {useState} from "react";
function Counter(props){
const [count, setCount] = userState(0);
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button> onClick={() => setCount(count + 1)}>
클릭
</button>
</div>
);
}
- 따라서 이처럼 const[변수명, set메서드명] = useState(초기값)을 통해 변수를 State처럼 바꿔주어 변경시 재랜더링이 발행하게 해야 한다.
- setCount()을 통해 count 변수가 변경되면 재랜더링이 된다.
Side Effect
- 부작용이 아닌 효과, 영향을 의미한다.
- 서버에서 데이터를 받아오거나 수동으로 돔을 변경하는 것을 의미한다.
- 작업들이 다른 컴포넌트에 영향을 미칠 수 있으며 렌더링 중에는 작업이 완료 될 수 없기 때문.
useEffect(이펙트 함수, 의존성 배열)
- 리액트의 함수 컴포넌트에서 side effect를 실행할 수 있게 해주는 훅을 의미한다.
- 해당 메서드 만으로 라이프사이르 메서드 사용이 가능
- 의존성 배열은 배열의 값이 하나라도 변경된다면 이펙트 함수가 실행되는 구조이다.
- 이펙트함수는 첫 랜더링, 업데이트 후 재랜더링 후 실행된다.
useEffect(이펙트함수, [])
- 의존성 배열에 빈배열이 들어갈 경우 컴포넌트가 moutn,unmount될 때 단 한번씩만 실행된다.
import React, {useState} from "react";
function Counter(props){
const [count, setCount] = userState(0);
//componentDidMount, componentDidUpdate와 비슷하게 작동합니다.
useEffect(() => {
// 브라우저 API를 사용해서 document의 title을 업데이트 합니다.
document.title = `You clicked ${count} times`;
});
return (
<div>
<p>총 {count}번 클릭했습니다.</p>
<button> onClick={() => setCount(count + 1)}>
클릭
</button>
</div>
);
}
- 위 코드에서 useEffect함수는 의존성 배열이 없기 때문에 리액트는 돔이 변경된 이후에 이펙트함수가 실행된다.
useMemo
- Memoized value를 반환하는 훅.
Memoized value의 의미
- 우선 Memoization이라는 개념을 알아야 한다.
- 이는 최적화와 관련된 개념인데 연상량이 많은 함수의 호출값을 저장했다가 재호출시 저장된 값을 반환하는 것을 의미한다.
- 이 저장된 값을 Memoized value라고 한다.
useMeme()의 사용법
const memoizdValue = useMemo(
() =>{
// 연산량이 높은 작업을 수행하여 결과를 반환
return computeExpensiveValue(의존성 변수1, 의존성 변수2);
},
[의존성 변수1, 의존성 변수2]
);
- 함수를 사용해 memoization을 구현한 것으로 []안의 의존성 변수에 변화가 있을 때, 새로 create함수를 실행하여 결과값이 반환되고 그렇지 않을 경우 이전에 반환되었던 값을 가지고 있다가 그대로 반환한다.
- 이를 통해 빠른 렌더링 속도를 가질 수 있다.
- 주의점은 useMemo로 전달되는 함수는 렌더링이 일어나는 동안 실행된다는 것.
- 때문에 렌더링 중간에 돌아가면 안되는 작업을 useMemo의 함수로 넣으면 안된다.
const memoizedvalue = useMemo(
() => computeExpensiveValue(a,b)
);
- 이 코드처럼 함수만 존재하고 의존성 배열이 없을 경우 랜더링을 할 때마다 함수가 실행되게 된다.
const memoizedvalue = useMemo(
() => {computeExpensiveValue(a,b);
}, []
);
- 의존성 배열이 빈 배열로 들어갈 경우 컴포넌트 마운트 시에만 호출된다.
- 대부분의 경우에 의존성 배열에 값을 넣고 변경이 있을 때 함수가 돌아가는 경우에 사용한다.
useCallback()
- useMemo()는 값을 반환하지만 함수를 반환하다.
- 컴포포넌트가 렌더링 될 때마가 함수를 매번 정의하는 것이 아닌 의존성 배열 값이 바뀔 때만 함수를 정의한다.
const memoizedCallback= useCallback(
() => {
doSomething(의존성 변수1, 의존성 변수2);
}, [의존성 변수1, 의존성 변수2]
);
- memoizedCallback 함수에서는 수행할 함수(콜백함수라고 부른다)와 의존성 배열을 파라미터로 받는다.
- 의존성 배열에 변화가 생기면 Memoization된 콜백함수(doSomething)을 반환한다.
useRef
- Reference란 특정 컴포넌트에 접글할 수 있는 객체를 의미한다.
-
이 레퍼런스 객체를 반환하는 함수가 바로 useRef()인 것이다.
- 레퍼런스 객체에는 current라는 속성이 있는데 이것은 현재 참조하고 있는 element를 의미한다.
const refContatiner = useRef(초깃값);
- 위 예시처럼 초기값을 넣으면 레퍼런스 객체가 반환된다. 이 객체는 컴포넌트의 라이프타임 전체에 걸쳐 유지된다.
- 컴포넌트가 유지되는 동안 내부의 current라는 속성을 가지고 있으며 이 값은 변경될 수 있는 상태이다. 즉 레퍼런스는 변경가능한 current라는 어떤 값을 담고 있는 객체인 것
Hook의 규칙
- 무조건 리액트 컴포넌트의 최상위 레벨에서만 호출해야 한다.
- 반복문, 중첩된 함수, 조건문에서 호출 금지
- 이때 훅은 컴포넌트가 렌더링될 때마다 매번 같은 순서로 호출되어야 한다.
function Mycomponent(props){
const [name, setName] = useState('Inje');
if(name !== ''){
useEffect(() => {
....
});
}
}
- 위 예시는 잘못된 훅 사용의 예시기이다 useEffect()가 조건문 안에서 사용되었다.
- 만약 조건문이 실행되지 않으면 훅이 사용되지 않으므로 최상위 레벨에서 사용된다는 규칙을 위반한다.
- 리액트 함수 컴포넌트에서만 Hook을 호출해야 한다.
- 일반 자바스크립트 함수에서 호출하면 안된다.
댓글남기기