useEffect (콜백함수)
렌더링이 완료된 후, JSX return 후에, 콜백함수를 실행
콘솔에 찍힌 순서
함수 본문에서 바로 실행한 side effect가 먼저 출력
그 다음, return 문 위에 있는 render라는 콘솔이 출력
렌더링이 일어난 뒤에 useEffect 활용한 side effect with useEffect 출력 - "render" 보다 위에 있지만, 콜백으로 전달 받은 이 printConsole이란 함수를 렌더링이 모두 완료되고 난 후에 실행할 수 있게 해준다. 이로 인해 우리는 사이드 이펙트가 렌더링을 blocking하지 않고 먼저 렌더링이 다 된 후에 우리가 원하는 사이드 이펙트를 수행할 수 있게 되는 것이다. => side effect가 렌더링을 blocking 하는 문제 해결!
아래도 동일한 결과!
아직 side effect가 매번 실행되는 문제는 해결하지 못했다. 위의 사진에서 side effect with useEffect가 계속 실행될 것이다. 어떻게 해결해야 할까?
컴포넌트의 state 또는 props가 변경될 때 마다 리렌더링이 된다. 리렌더링은 곧 App이라는 함수 컴포넌트를 다시 한 번 호출한다라는 행위다.
렌더링이 모두 된 후에 side effect가 실행된다.
하지만 매번 렌더링이 될 때마다 이 side effect는 매번 발생하고 있다. -> 문제점 발생. 비효율적인 프로그램이 된다.
useEffect는 콜백함수라는 하나의 인자만 받는 것이 아니다. 두 번째 인자로 의존성 배열이라고 부르는 인자를 하나 더 받는다. 배열의 형태를 가지고 있다. useEffect에 이 의존성 배열을 인자로 전달하게 되면, useEffect의 동작은 먼저 처음으로 의존서 배열의 값을 검사할 것이다. 여기서 검사한다는 것은 의존성 배열에 들어가 있는 값이 이전 렌더링과 비교했을 때 동일한지 검사를 한다는 것이다. 검사가 됐으면 조건에 따라 콜백 함수를 호출해 준다.
첫번째 렌더링에서는 무조건 콜백함수를 호출한다. 두 번째 렌더링부터는 의존성 배열의 값이 변했으면 콜백 함수를 호출하고, 만약 변하지 않았다면 콜백 함수를 호출하지 않는다.
count의 값이 변했으니 - count changed 라는 콜백함수를 실행
input에 글을 썼을 때는(텍스트의 값을 변화시켰을 때는) - count changed라는 콘솔은 찍히지 않았다.
분명히 리렌더링은 됐고 카운트는 1이고, 텍스트는 1로 바뀌었고 렌더링이 됐다는 콘솔도 찍혔지만, count changed라는 side effect는 이 상황에서 발생하지 않았다.
즉 count가 바뀐 것이 아니라 텍스트가 바뀌었기 때문에 useEffect는 발생하지 않는 것이다.
useEffect에 count 대신 text를 의존성 배열에 넣게 되면 어떻게 될까?
의존성 배열이 (두 번째 인자로) 전달되지 않으면 매번 렌더링마다 이 side effect가(콜백 함수가) 발생하게 되는 것이다.
의존성 배열에 인자를 전달하면 리액트가 렌더링마다 이 의존성 배열에 있는 값을 검사하고 이 값이 변했을 때만 실제 함수를 호출하게 된다.
의존성 배열에 두 가지(count, text) 값을 전달하면 어떻게 될까?
여러 가지 값을 넣게 되면, 의존성 배열은 그 중 하나라도 변했다면 이펙트를 실행시켜 준다.
첫번째 렌더링 때에만 이펙트가 실행되기를 원하고, 두 번째 렌더링부터 마지막까지 절대 호출되지 않기를 원하는 콜백함수가 있을 경우에는 어떤 식으로 표현할 수 있을까? 빈 배열을 넣으면 된다! 빈 배열을 넣게 되면 변화를 감지할 값이 없게 된다. 변화를 감지할 값이 없기 때문에 첫 번째 렌더링에만 이펙트가 호출이 되고 두 번째 렌더링부터 값이 변한 것을 판단할 수 없기 때문에 이 이펙트는 첫 번째 렌더링 이후에는 절대 실행 되지 않는다.
clean up
무엇을? 계속해서 남아있는 effect들은 한 번 정리를 해주고 치운 다음에 새로운 이펙트를 발생시키거나 최종적으로 치워준다.
불필요한 동작들이 계속해서 발생할 때 - clean up 필요. 우리가 필요할 때만 사용할 수 있도록
clean up을 하면서 동작하고 싶은 것을 함수 형태로 만들어서 return 한다.
한 번만 콘솔에 찍힌다.
⬆️ 변수 선언하고 리턴하지 말고, 리턴 쓰고 바로 함수 적을 것.
컴포넌트가 언마운트 될 때도 클린 업 함수를 호출해준다.
이후에