side effect(부수 효과)가 정확히 무엇일까요?
부수 효과란
앱이 제대로 동작하기 위해 실행되어야 하지만
현재의 컴포넌트 렌더링 과정에
직접적인 영향을 미치지는 않는
작업라고 할 수 있습니다
리액트 앱의 맥락에서 보면
부수 효과란 다음과 같습니다
꼭 실행되어야만 하는 작업이지만
현 컴포넌트 렌더링 과정에
직접적이고 즉각적인 영향을 미치지 않는 것입니다
이 정의도 꽤나 모호할 수 있습니다
예시를 한번 들어 보겠습니다
예를 들어, 이 데모 앱에서
웹사이트 사용자로부터의 거리를 기준으로
이 장소들을 거리순으로 정렬해 보겠습니다
사하라 사막 근처에 거주하고 있다면
이 카드가 먼저 나오게 될 것이고
나머지 카드들 또한 위치에 따라
거리순으로 정렬될 것입니다
이것이 작업의 내용입니다
그래서 이 loc.js 파일을 마련해 둔 것인데
제가 준비해둔 함수는 이미
지구상의 어느 곳이든
위도와 경도 좌표로 표현이 가능하도록
두 지점간 거리를 계산할 수 있는
기능을 갖추고 있기 때문입니다
그리고 여기에서
sortPlacesByDistance 함수를 사용해
장소의 배열을 input으로 받는데
이 것은 data.js 파일이 정의하는 장소들이고
결과적으로는 사용자 위치를 기반으로
거리순으로 정렬된 목록을 만들어 냅니다
이것은 한 가지 매우 중요한 것을 의미합니다
바로 우리가 이 웹사이트 사용자의 위치를 알아야 한다는 것입니다
다행히도, 적어도 이론적으로
브라우저에서는 그렇게 어려운 일이 아닙니다
그 위치를 얻기 위해 호출할 수 있는
빌트인 브라우저 method(메소드)가 있기 때문입니다
이를 위해서는 앱 컴포넌트로 들어가야 하는데
그 이유는 물론, 최대한 빨리
말하자면 이 앱의 시작점에서부터 이 위치를 얻고자 하기 때문입니다
이제 이용자의 위치를 알아내야 하는데
여러분도 아시다시피 이 앱 컴포넌트는 대부분의 리액트 앱에서
루트(root) 컴포넌트를 담당하고 있고
이 리액트 앱에서도 마찬가지입니다
그렇기 때문에 이 앱 컴포넌트의 함수가
사용자의 위치를 파악하기 알맞은 곳이라고 할 수 있습니다
자 그러면 이 쪽으로 와서
사용자의 위치를 얻기 위한 코드를 추가할 수 있는데
브라우저 에서는
navigator 객체의 사용이 수반됩니다
이것은 브라우저가 해당 브라우저 내에서 구동되는
자바스크립트 코드에 노출시키는 객체이기도 합니다
그러므로 navigator는 제가 정의하는 것도 아니고
리액트가 제공하지도 않지만
대신 브라우저가 제공하는 것입니다
이 전세계적으로 사용가능한 navigator 객체에
공간 위치 객체를 붙여주고
웹사이트 사용자의
현재 위치를 호출할 수 있도록
getCurrentPosition 메소드를 붙여넣어 주겠습니다
이 메소드를 호출하게 되면
사용자는 위치 제공 여부 확인을 요구받게 되고
동의를 받았을 경우
위치 파악이 진행됩니다
위치를 파악하는 것은
어느 정도 시간이 소요될 수 있기 때문에
getCurrentPosition 기능은
콜백(Callback) 함수를 필요로 합니다
이것은 하나의 함수를 입력값으로 삼는데
제가 여기 정의하는 것처럼
익명의 화살표 함수을 예시로 들자면
위치가 파악된 후
브라우저에 의해 실행되는 것인데
이것은 몇 천분의 1초, 또는 오래 걸리는 경우
수 초 정도의 시간이 지나고 난 이후일 것입니다
그러므로 이 위치에 의존하는 코드는
이 함수 내에서 실행되어야 하는데
위치가 확인된 후 브라우저로부터 호출받는 것이
바로 이 함수이기 때문입니다
그래서 제가 호출하고자 하는 sortPlacesByDistance를 여기에 두는 것입니다
제가 loc.js 에서 내보내는 이 함수는
여기로 불러와야 합니다
loc.js 에서 sorPlacesByDistance를 가져와서
여기로 호출하는 것입니다
그리고 이 함수에게
data.js 파일에서 불러온
이 배열을 전달하면 되는데 이것은
가짜 장소를 모아둔 배열입니다
그리고 나서는
사용자의 위도와 경도 좌표를 제공해야 합니다
getCurrentPosition을 통해 얻은 것인데
브라우저는 찾아낸 위치를
position 객체를 통해 노출시키고
그것은 자동으로 이 함수로 전달됩니다
기억해 두셔야 할 것은
이 함수는 브라우저로부터 호출받는 것이고
사용자의 위치가 포함된 객체를 우리에게 주는 것 또한
브라우저라는 것입니다
이제 우리는 이 position 객체를 이용해서
중첩된 객체의 위치인 coords에 접근해서
여기에 위도인 latitude를 덧붙입니다
그리고 거리순 정렬을 위한 세 번째 인수로
position.coords.longitude를 전달해 줍니다
이렇게 하고나면 sortPlacesByDistance 함수에는
사용자 위치의 latitude(위도)와 longitude(경도)의
좌표가 전달되는 것입니다
이제 이것은 정렬된 장소의 배열을 반환하므로
이제 그것을 이 앱에서 사용할 수 있습니다
그리고 여기서부터 일이 어려워집니다
그 이유는 여기 있는 코드 전체가
곧 부수 효과이기 때문입니다
이것이 부수 효과인 이유는
이 코드가, 그리고 사용자의 위치가
이 앱에 필요하기는 하지만
이 컴포넌트 함수의 주된 목적과는
직접적인 연관성이 없기 때문인데
모든 컴포넌트 함수의 주된 목적은
렌더링이 가능한 jsx 코드를 반환하는 것이기 때문입니다
그리고 여기 이 코드는 그 작업과
직접적으로 연관되어 있지 않기에 부수 효과인 것입니다
이 컴포넌트의 다른 코드는 모두 연관되어 있습니다
클릭에 대한 리스너(listener)를 설정하는 것도
JSX 코드에 필요한 부분이고
설정 또한상태
화면에 보여지는 것에 영향을 주기 때문입니다
그러나 사용자의 위치를 파악하는 이 코드는
직접적으로 연관되어 있지 않습니다
특히나 이 코드의 경우에는
즉각적으로 완료되지 않습니다
대신, 이 콜백 함수는
미래의 언젠가 호출되기는 하겠지만
그건 아마도 이 앱 컴포넌트의 함수가
이미 모두 실행된 이후일 것입니다
그렇기에 이것은 부수 효과입니다