자 그렇다면 이 문제를 해결하기 위해
리액트의 useEffect 훅을 어떻게 사용하면
부수 효과를 좋은 방향으로 다룰 수 있을까요?
가장 먼저 해야 할 일은
리액트에서 useEffect를 가져오는 것입니다
불러온 뒤에는 다른 훅과 마찬가지로
컴포넌트 함수에서앱
실행되어야만 합니다
다만 useEffect의 경우에는 useState나 useRef와는 다르게
값을 반환하지 않습니다
대신 useEffect는 두 개의 인수를 필요로 합니다
첫 번째는 부수 효과 코드를
묶어줄 함수입니다
이 경우에는
여기 이렇게 익명 함수를 생성해서
이 익명 함수로 위치 파악을 해주는
상태 업데이트 코드를 옮겨 오겠습니다
이것은 첫 번째 단계일 뿐
아직 다 끝난 것이 아닙니다
이제 useEffect에 두 번째 인수를 전달해야 합니다
익명 함수를 만들어둔 이후에는
두 번째 인수로 dependency(의존성) 배열을 만들어
해당 Effect 함수에 넣어 주어야 합니다
의존성에 대해서는 이후에 다루도록 하고
일단은 빈 배열을 추가하겠습니다
자 이렇게 하고 나면
코드가 이런 모습이 되어 있을 텐데
이것으로 여러분은 무한 루프 문제에서 벗어나게 됩니다
그 이유는
useEffect가 의도하는 바는
useEffect로 전달하는 첫 인수인
이 함수가 리액트로 인해 실행되는 시점입니다
이 시점이 매우 중요합니다
그 시점이 매번 컴포넌트가 실행된 이후인데
그러니까 앱이 시작되고
앱 컴포넌트 함수가 실행되어도
이 코드는 즉시 실행되지 않는다는 것입니다
앱 컴포넌트 함수의 실행이
모두 완료된 이후에 실행되기 때문입니다
이 JSX 코드가 반환된 후의 시점에서야
useEffect에 전달해둔 부수 효과 함수를
리액트가 실행시킨다는 것입니다
리액트는 컴포넌트 함수의 실행이 완료된 후에
이것을 실행시키게 됩니다
이제 여기 있는 상태를 업데이트하면
여러분이 배우신대로 컴포넌트 함수가 다시 실행될 것입니다
이론적으로는 이 Effect 함수도 다시 실행되겠지만
거기에 이 의존성 배열이 들어옵니다
이 의존성 배열을 정의해 주는데
누락되지 않도록 정의해 주어야 합니다
그렇게 하면 리액트는
그곳에 명시된 의존성을 살펴볼 것입니다
그리고 이 의존성의 값이 변화했을 경우에 한해
이 Effect 함수를 재실행시킬 것입니다
다소 추상적으로 들리실 수 있으니
의존성의 사용 사례를
조금 후에 보여 드리도록 하겠습니다
여기에는 의존성이 없습니다
가지고 있는 것이 없으니 변화할 수도 없습니다
그렇기에 절대 바뀌지 않습니다
그러므로 리액트로서는
이 이펙트 함수를 재실행할 일이 없는 것입니다
대신에 앱 컴포넌트 함수가
처음으로 실행된 이후에
단 한번 실행하게 됩니다
그 이후에는 이 Effect 함수가 실행될 일이 없습니다
이 의존성 배열을 누락하면
앱 컴포넌트 렌더링 과정이 끝날 때마다
Effect 함수가 재실행될 것이고
그렇게 되면 무한 루프에 빠지게 됩니다
그러나 빈 의존성 배열을 설정해 두면
그런 일이 생기지 않기 때문에
이 문제는 해결되는 것입니다
무한 루프를 생성하지 않으면서
사용자의 위치를 알아내는 데에 성공했다면
이제 availablePlace를
정렬된 availablePlaces로 설정해 주겠습니다
그리고 앱 약간만 조정해 주고
여기 아래에 있는 Places 컴포넌트에는
이 컴포넌트의 지원을 받는
fallbackText 속성을 추가하고
여기에 '장소를 거리순으로 정렬합니다'라고 입력하겠습니다
이것은 아직 장소 정렬이 되지 않았을 때
사용자에게 보여 줄 fallback(대체) 텍스트입니다
우리가 사용자의 위치를 파악하는 중이기 때문입니다
물론 애초에 아무런 장소가 확보되지 않았기 때문에
여기 이렇게 빈 배열로 시작하는 것입니다
이제 이것을 모두 저장하고 새로고침을 해 보면
이렇게 작은 창이 뜨면서
사용자의 위치 정보 수집에 대한 동의 여부를 묻습니다
만약 차단을 클릭한다면 앱이 망가질테니
승인 버튼을 클릭해 주겠습니다
이제 제 위치를 알아보기 시작할텐데
이 과정은 말씀드렸듯이 약간의 시간이 소요됩니다
그러고 나면 제 위치와의 거리를 기준으로
이 장소들을 정렬해서 보여줍니다
물론, 여러분의 위치에 따라
순서는 다르게 보일 수 있습니다
제 경우에는 꽤 정확한 것처럼 보입니다
이 모든 장소를 확인해 보지는 않았습니다만
어차피 가짜 데이터일 뿐이기도 하고, 보기에도 정확해 보입니다
콘솔에도 아무런 오류가 없습니다
그러므로 이 코드는 잘 동작하는 것으로 보이고
이렇게 앱을 망가뜨리지 않으면서
부수 효과를 다룰 수 있었습니다
문제가 없다는 건 언제나 좋은 일입니다