useEffect(()=>{
console.log("");
})
useEffect는 기본적으로 componentDidMount, componentDidUpdate, componentWillUnmount, getDerivedStateFromProps의 역할을 모두 합니다.
때문에 위 코드는 1) 컴포넌트가 마운트 된 후, 2) 컴포넌트가 업데이트되고 난 후 3) 컴포넌트가 언마운트 되기 전 모두 실행됩니다.
useEffect(<function>, <array>);
useEffect는 함수를 반환할 수 있습니다. 이를 이라고 표현합니다.
clean-up
useEffect(()=>{
console.log("");
return(() => func());
})
constructor가 가장 먼저 실행
getDerivedStateFromProps에서 props와 state를 비교
render component
update DOM
componentDidMount가 실행
getDerivedStateFromProps에서 props와 state 비교
shouldComponentUpdate 실행 - new props, state를 확인하고 rerender 할 것인지 결정
rerender
update DOM
componentDidUpdate 실행
useEffect(()=>{
console.log("componentDidMount");
},[])
//컴포넌트 마운트시에만 실행됩니다.
cosnt { exampleProp } = props;
const [count, setCount] = useState(0);
//일단 마운트 될 때 무조건 실행되고
useEffect(() => {
console.log("count or exampleProp changed");
},[count, exampleProp]);
//조건에 특정 state 혹은 props를 전달하면 이 state 혹은 props가 변할 때만 useEffect가 실행됩니다.
// 클래스의 경우 -> constructor -> render -> ref -> componentDidMount
// (setState/props 바뀔때) -> shouldComponentUpdate(true) -> render -> componentDidUpdate
// 부모가 나를 없앴을 때 -> componentWillUnmount -> 소멸
useEffect(() => {
//보통 ajax
console.log('componentDidMount에서만 실행');
}, []);
// 만약 componentDidUpate()에서만 실행하게 하고 싶다 라고 하면
// 패턴이니까 기억해두기
const mounted = useRef(false);
useEffect( () => {
if(!mounted.current){
mounted.current = true;
}else{
//ajax
}
},['바뀌는 값']); //componentDidMount에서는 실행 안함
위 코드를 custom hooks 으로 작성
//오직 state가 변경될 때만 useEffect 실행하도록 customhooks 작성...
export default function useUpdateEffect(fn, dependencies = []) {
const isInitialMount = useRef(false);
useEffect(() => {
if (!isInitialMount.current) {
isInitialMount.current = true;
} else {
return fn();
}
}, dependencies);
}
//사용시
useUpdateEffect(() => {
console.log(loginDone, 'loginError', loginError);
if (loginDone) {
alert('로그인 성공'); //매번 랜더링 될 때마다 실행되네.. home애서 실행하도록 해야겠다...
setLoginVisible(false);
//console.log('쿠키는?', document.cookie);
}
if (loginError) {
alert('로그인 실패');
return;
}
}, [loginDone, loginError]);
useEffect(() => {
//console.log('loginLoading: ', loginLoading, 'joinLoaing', joinLoading);
//console.log('loginDone', loginDone, 'trigger 안 되는디..');
//console.log('joinDone', joinDone, 'trigger 안 되는디..');
//왜 여기서 바로 반영이 안 되는 거지...진짜 짜증나네...이유를 모르겠으니까 답답해 뒤지겄네..
//당연히 랜더링 자체가 되지 않으니 실행이 안 되는 거네... 바보였는가...
console.log('data', data);
if (data) {
console.log('null이 아니라면', data.msg);
}
}, [loginLoading, joinLoading, data]);
당연히 랜더링 자체가 되지 않으니 실행이 안 되는 거네... 바보였는가...!!!!!!
https://overreacted.io/ko/a-complete-guide-to-useeffect/
https://ko.reactjs.org/docs/hooks-effect.html
https://daveceddia.com/useeffect-hook-examples/#useeffect-does-not-actively-watch
React useEffect only on Update
https://www.robinwieruch.de/react-useeffect-only-on-update
https://jungpaeng.tistory.com/92
https://stackoverflow.com/questions/55075604/react-hooks-useeffect-only-on-update
https://stackoverflow.com/questions/53179075/with-useeffect-how-can-i-skip-applying-an-effect-upon-the-initial-render
useEffect(()=>{
console.log("");
return(() => {//정리 });
})
- ComponentWillUnmonut의 역할은 clean-up 함수를 통해 구현할 수 있습니다.
- 컴포넌트가 Unmount될 때 정리하거나 unscribe 해야할 것이 있다면 useEffect의 return 값으로 전달합니다.
useEffect(() => { //하나의 예시
// scroll 이벤트를 만들어줍니다. 스크롤을 움직일때 마다
// onScroll 함수가 실행됩니다.
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll); <---- 집중 !!!
}, []);
return state;
};
https://velog.io/@jeonghoheo/React-Hooks리액트-훅스의-기본-Part-1-2jjxpaobgg
useeffect에 등록되는 함수에 asyn를 붙이면 안 됨. 반환되는 값은 뒷정리 함수이기 때문
함수 내부에는 가능
loading이라는 상태도 관리하여 api 요청이 대기 중인지 판별, 요청이 대기중일 때 loading 값이 true가 됨
import React, { useEffect, useState } from 'react';
export default function usePromise(promiseCreator, deps) {
const [loading, setLoaing] = useState(false);
const [resolved, setResolved] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const process = async () => {
setLoaing(true);
try {
const resolved = await promiseCreator();
setResolved(resolved);
} catch (error) {
setError(error);
}
setLoaing(false);
};
process();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
return [loading, resolved, error];
}