invalid Hook call 에러가 나는 원인에는 여러가지가 있는데 Hook에 대해 잘 모르는 상태로 쓸 때 에러 확률이 높다.
특히 커스텀 Hook을 만들어 사용할때!
Custom Hook을 쓰는 이유는 use로 시작하는 여러가지 Hook을 하나로 묶기 위함임.
useEffect
목적 : 뭔가가 바뀌면 어떤 동작을 자동으로 실행하기 위해 사용한다.
인자
인라인 콜백함수: 의존성 리스트에 있는 항목 중의 하나가 업데이트 되면 실행시킬 동작
의존성 리스트: 이 리스트에 있는 요소가 업데이트되면 콜백함수를 다시 작동.
useEffect(()=>{어떤 동작},[뭔가]);
사용 예
useState와 함께 사용하는 예시
const [ state, setState ] = useStae('idle'); //프로세스의 진행상태를 저장하는 state
useEffect(()=>{
if(state ==== 'success'){ //state가 success일때만 if문이 실행.
console.log("PROCESS DONE!! <<success>>");
setState('idle'); //state를 초기상태로 돌려줌.
}
},[state]); //프로세스가 idle -> pending -> success/fail로 바뀔 때 마다 UseEffect로 감싼 부분 실행.
* idle: 프로그램을 수행하지 않는 상태(프로세스가 아님) ex) I/O 인터럽트 대기중이거나 준비 큐에서 대기하거나 sleep하고 있거나....
useCallback
사용 목적
원하는 타이밍에 호출시킬 함수를 만들기 위해 사용(함수가 반환)
인자
인라인 콜백함수: 원하는 타이밍에 동작시킬 동작
의존성 리스트: 의존성에 포함된 요소가 업데이트 될 경우, 반환되는 함수도 갱신됨
사용 예
useEffect, useState와 함께 사용하는 예시
const [ food, setFood ] = useState('샐러드');
const [ menuAsked, setMenuAsked ] = useState(false);
useEffect(()=>{
if(menuAsked === true){
printMenu();
setMenuAsked(false); //state를 초기상태로 돌려줌.
}
},[menuAsked])
const printMenu useCallback(()=>{
console.log(`[Today's Dinner Menu : ${food}]`);
},[food]);
설명
menuAsked의 상태가 바뀔때마다 useEffect의 인라인 콜백함수가 실행되고, menuAsked의 상태가 true라면 printMenu 함수가 호출된다. 코드가 실행되는 동안 food의 상태가 바뀌지 않는다면 printMenu 함수의 내용도 바뀌지 않음.
동작 | food | menueAsked | printMenu | 함수 변화 출력 |
최초 상태 | '샐러드' | false | x | - |
setFood('고추장 삼겹살') | '고추장 삼겹살' | false | o | - |
setFood('갈치구이') | '갈치구이' | false | o | - |
setMenueAsked(true) | '갈치구이' | true | x | [Today's Dinner Menu: 갈치구이] |
useMemo
사용 목적
useCallback은 원하는 타이밍에 실행시킬 함수를 만드는데 사용
그에 비해 useMemo는 원한느 값을 업데이트하기 위해 사용
인자
인라인콜백
의존성 리스트: 이 배열이 없으면 렌더링마다 새 값을 계산함.
사용 예
const person = useMemo(
()=>(
<Person
name={name}
song={favoriteSong}
/>
),
[name, favoriteSong]
);
- name, favoriteSong이 바뀌면 값을 새로 계산.
- name, favoriteSong이 바뀌지 않으면 값을 새로 계산하지 않고 기억해두었던 이전의 값을 사용
- 렌더링 중에 실행됨
- useMemo를 사용하지 않아도 코드가 동작해야하며, 쓸데없는 리렌더를 줄이기 위해 사용(최적화)
useEffect vs useCallback
useEffect는 어떤 값의 변화가 동작을 자동으로 불러오도록 하고 싶을때,
useCallback은 어떤 값이 변했을때 특정 동작을 값에 따라 다르게 실행시키고 싶거나 원하는 타이밍에 어떤 동작을 실행시키고 싶을때 적합하다.
State를 바라보고 있다가 effect를 주는 것인데 이때의 effect는 멱등성이 유지된다.
그에 비해 useCallback은 state에 따라 다른 동작을 하는 함수를 리턴할 수 있으므로 동작을 state에 따라 다르게 주고 싶을때 유용.
useMemo는 값을 리턴하며, 최적화에 방점이 찍힌다.
추가
useState와 useMemo의 사용처 비교
useState를 쓸 수 밖에 없는 상황을 제외하고는 useMemo로 감싼 const로 선언하여 사용하는 것이 좋다.
아래처럼 의존성에 따라 값이 자동적으로 바뀌는 경우엔 useState를 사용할 이유가 없다.(자동갱신에 가까움)
//b와 c를 더한 값이 a가 되는 경우
const a = useMemo(()=>{b+c}, [b,c]);
그러나 아래의 경우처럼 server에서 값을 받아오거나 사용자로부터 입력을 받는 경우(onChange마다 변경이 일어남)에는 useState를 사용한다.
// useState를 쓸 수 밖에 없는 상황
const [name, setName] = useState('');
const [email, setEmail] = useState('');
(생략)
// 1. get data from server
fetch(domain).then((res) => setName(res.data.name));
(생략)
// 2. get data from user input
return(
<Form>
<label css={labelStyle} htmlFor="email"> Email </label>
<input
type='email'
id='email'
value={email}
(...)
onChange={(event) => setEmail(event.currentTarget.value)}
/>
</Form>
)
Reference
본문 발췌 from
https://intrepidgeeks.com/tutorial/usage-and-differences-of-hook-useeffect-usememoand-usecallback
[Hook] useEffect, useMemo 그리고 useCallback 각 사용법과 차이
Invalid Hook call 에러가 나는 원인에는 여러가지가 있는데, Hook에 대해서 잘 모르는 상태로 썼을때 에러가 날 확률이 높아진다. 특히 커스텀 Hook을 만들어 사용할때 이런 개념들을 모르고 쓰면 코드
intrepidgeeks.com
'Sparta x 이노베이션 캠프 > React' 카테고리의 다른 글
TIL : dangerouslySetInnerHTML, DOMPurify (0) | 2022.10.09 |
---|---|
TIL : 이벤트 버블링과 캡처링 (0) | 2022.10.06 |
TIL: useRef (0) | 2022.10.04 |
TIL: useEffect (0) | 2022.09.30 |
TIL: 서버에 데이터 보내기. formData, JSON.stringify() 방식 왜 쓰는가? (0) | 2022.09.29 |