이 useFetch 훅을 제대로 작동시키기 위해서는
상태값을 입력해 주는 작업이 필요합니다
나중에 이 커스텀 훅을 사용하는 모든 컴포넌트가
그 훅에 입력된 같은 상태값이
필요해지기 때문입니다
값을 새롭게 다시 입력할 필요가 없는 것입니다
결과적으로는 그 커스텀 훅의
재사용성이 높아지게 됩니다
이 커스텀 훅은 단순히 요청을 보내는 것이 아니라
연관된 모든 state 값을 관리하는 역할을 합니다
이 커스텀 훅을 재사용 할 수 있게 만들기 위해서는
여기서 useState 함수를 사용해야 합니다
결과적으로는 우리가 isLoading 상태
혹은 전에 이름 지었던 것처럼 isFetching 상태를 관리할 수 있게 됩니다
물론 이 과정에서 오류가 발생할 수도 있습니다
오류가 발생하면 새로운 상태 값으로 관리해야 합니다
[error, setError]를 입력하겠습니다
결국에는 HTTP 요청을 보내기 위해 지금 작업하는 것이기 때문에
데이터를 불러올 수밖에 없습니다
이 커스텀 훅을 만드는 이유가
다양한 상황에서 사용하기 위함임은 맞지만
저는 다른 유형의 데이터에
userPlaces 같은 이름을 붙이고 싶지는 않고
data나 fetchedData나 setFetched Data 같은
조금 더 평범한 이름을 붙이고 싶습니다
그리고 여기에는 상태값을
정의되지 않은 undefined로 입력합니다
그리고 제가 앞서 fetchedData를 입력한 곳에
setFetchedData를 불러오겠습니다
물론, 여기 쓰인 코드도 그리 일반적이지는 않습니다
제가 한 작업은 userPlaces를 가져오기 위한 목적입니다
이 코드를 조금 더 다양한 상황에서 사용할 수 있다면
더 좋을 것입니다
여기서 유념할 부분이 있습니다
커스텀 훅은 하나의 함수일 뿐입니다
다른 모든 함수처럼, 커스텀 훅도 parameter를 사용할 수 있습니다
그렇다면 여기서 매개변수로
함수를 가져오기 위해 fetchFn을 가져오겠습니다
물론 매개변수의 이름은 원하는 대로 정할 수 있습니다
여기서 fetchFn을 실행시켜서
이 커스텀 훅이 모든 fetchFn에서
사용될 수 있게 만들겠습니다
그렇게 되면 여기서 데이터를 다시 얻을 수 있는데
그 데이터를 fetchedData라고 지정해 뒀습니다
그렇게 되면 이 오류 메시지를 제외하고는
꽤 일반적으로 쓰일 수 있게 됩니다
그러면 여기서 이 오류 메시지를 설정하는
또다른 매개변수를 받을 수도 있고
혹은 더 흔한 오류 메시지로 고칠 수도 있습니다
예를 들어, '데이터 불러오기 실패'로 하겠습니다
고쳐야 하는 다른 부분은
이 함수의 이름입니다
fetchPlaces라는 이름을 사용하는 대신에
fetchData라는 이름을 사용해 보겠습니다
그렇게 되면 이 함수의 이름이 여기 적혀있게 됩니다
여기 노란색 물결 표시가 있습니다
이 표시가 보이실 겁니다
제가 여기서 이 fetchFn을 사용하고 있기 때문에
이 위에 마우스를 올려두면 설명이 나오는 것처럼
의존성으로 fetchFn을 추가해야 합니다
의존성은 useEffect로 정의되지 않는
외부 데이터이기 때문에
이론상으로는 바뀔 수 있습니다
만약 바뀌게 되면, 이 Effect도 다시 실행돼야 합니다
그래야 가장 최신의 fetchFn으로
데이터를 올바르게 불러올 수 있습니다
따라서 여기에 의존성으로 fecthFn을 입력해야 합니다
이것은 실행시키는 목적이 아니라
함수와 마찬가지로
값으로서 의존성으로 입력되는 것입니다
이렇게 하면, 재사용성이 좋은 useFetch 훅이 완성됩니다
하지만 지금 이 단계에서
이 모든 상태값으로 무언가를 하려고 하는 것은 아닙니다
단지 설정해 두는 작업일 뿐입니다
이 훅 안에서 상태값들은
아무 쓸모가 없는 상태입니다
이 커스텀 훅을 사용할 컴포넌트에
이 값들이 쓸모가 있도록 만드는 작업이 있습니다
기존 자바의 함수라면 무엇을 사용할지 고민해 봅시다
값을 반환하면
이 훅을 사용할 때
이 값들을 다시 불러올 수 있을 것입니다
그래서 이 훅의 마지막에
effect 함수 밖에서 이 값들을 반환할 수 있습니다
이 값들을 배열이나 객체로 그룹화할 수 있습니다
편한 방식을 고르면 됩니다
한 가지 유념할 사항은
useState 또한 값 반환이 가능하다는 것입니다
useFetch는 배열을 두 개의 요소로 반환합니다
두 요소는 스냅샷(snapshot) 상태와 Updating 함수 상태입니다
우리가 만든 커스텀 훅으로 같은 작업을 할 수도 있습니다
여기서 배열이나 객체를 반환할 수 있습니다
여기서는 객체를 반환하겠습니다
숫자만 반환할 수도 있긴 하지만
여기서 저는 데이터 3개를 반환하고 싶기 때문에
이걸 전부 그룹화하겠습니다
배열이나 객체로 그룹화할 수 있습니다
여기서는 객체로 그룹화하고
각각의 상태값을 핵심 값으로 넣어주겠습니다
isFetching, data, 그리고 error를 입력합니다
이 데이터의 이름은 fetchedData입니다
그래서 제가 만든 커스텀 훅에 있는 이 세 개의 상태값들을
객체로 그룹화하여 반환 할 것입니다
그리고 마지막으로
컴포넌트에서 이 훅을 사용하기 위해서
이 훅 함수를 추출해야 합니다
그렇다면, 앱 파일(App.jsx)로 넘어가서
우리가 이미 처리한 상태를 제거하고
useEffect 훅은 이미 제거된 상태이고
여기서 useFetch.js 파일에 있는 훅으로부터
useFetch를 가져올 수 있습니다
그럼, 이 fetch 함수를 useFetch로 이동시키기만 하면 됩니다
제가 정한 이름은 fetchUserPlaces였습니다
이 함수의 핵심은 HTTP 요청을 보내는
코드를 보유하고 있는 것입니다
그 결과 useFetch를 부르면
스냅샷 상태를 얻을 수 있게 됩니다
이 스냅샷 상태는 그룹화한 것을 객체로 반환한다는 의미입니다
그래서 이제 isFetching, error, 그리고 fetched Data를 얻기 위해서
객체 구조 분해(destructure)를 하겠습니다
컴포넌트에서 커스텀 훅을 사용할 때
이점이 있습니다
바로 커스텀 훅이 관리하는 모든 상태값이
커스텀 훅을 사용하고 있는
컴포넌트에 속한다는 것입니다
그래서 커스텀 훅에서 state 값을 업데이트하면
예를 들어, 여기
setIsFetching(true)가 발생하면
커스텀 훅이 있는 컴포넌트도 다시 실행되게 됩니다
컴포넌트 안에서 상태값을 조정한 것 같은
그런 효과가 나타나는 것입니다
커스텀 훅을 무언가 사이에 끼워 넣는
추가 층 같은 것으로
사용해도 같은 효과가 나타납니다
이 컴포넌트의 행동은 변하지 않습니다
하지만 이 컴포넌트에서 useFetch로 반환시킨
상태값을 사용할 수는 있습니다
이로 인해
우리가 다른 문제를 겪을 수도 있습니다
왜냐하면 우리가 이미 불러온 데이터를
업데이트시키는 작업과
어떤 부분을 선택했을 때 데이터를 바꾸는 작업을 했기 때문입니다
하지만, 이에 따라 발생하는 문제는 나중에 다루려고 합니다
일단 지금은 여기 있는 각기 다른 함수들을
주석 처리하여 삭제하겠습니다
그 함수들을 가리키게 해둔 속성도
주석 처리하여 삭제하겠습니다
여기도 주석 처리를 하겠습니다
그러면 이제 userPlaces를
fetchedData로 교체하겠습니다
여기에 fetchedData를 입력합니다
userPlaces를 계속 사용하고 싶으시다면
여기에 별칭을 지정할 수도 있습니다
구조 분해된 속성 이름 옆에 콜론을 붙이면 됩니다
그리고 userPlaces같이
여러분이 정한 별칭를 배정하면 됩니다
그렇게 하고 저장했을 때
화면처럼 오류가 생기는 것을 확인할 수 있습니다
여기서 오류가 발생하는 이유는
어딘가에 배열이 있을 것을 예상하고
length 프로퍼티에 접근하지만
우리가 찾는 것은 undefined뿐입니다
이런 일이 발생하는 이유는
제가 처음에 userPlaces를 이렇게 빈 배열로 입력했기 때문입니다
더 일반적으로 사용할 수 있는 useFetch function에서는
이처럼 입력 시기에는 undefined 상태로 놔둡니다
이 훅을 다양한 상황에서
활용할 수 있지만
모든 상황에서 서버로부터 배열을 가져오지는 않기 때문입니다
대신 여기에 간단하게 새로운 매개변수를 받아들일 수도 있습니다
예를 들어 initialValue라고 입력합시다
이걸 실제 초기값으로 설정할 수 있습니다
그럼 더 구성적으로 보이게 됩니다
다시 앱 파일(App.jsx)로 넘어와서
이제 userPlaces에서 useFetch로 우리가 원하는 초기값을
두 번째 인수로서 넘겨올 수 있게 됩니다
이 경우라면 빈 배열이 될 것입니다
그래서 우리가 아직
데이터가 없는 상태라면
이렇게 빈 배열이 나옵니다
그렇게 해서 저장을 누르고 새로고침 하면
불러온 장소들을 확인할 수 있을 것입니다
이것은 우리가 만든 커스텀 훅 덕분에 작동하는 것입니다
그리고 이런 목적으로 커스텀 훅을 사용하는 것입니다
useState나 useEffect같이
이미 빌트인되어 있는 훅을 사용하거나
이런 HTTP 요청을 만들 때 적용되는 모든 로직이
커스텀 훅에서도 똑같이 적용됩니다
그리고 컴포넌트에서 커스텀 훅만으로도
모든 쟉업이 가능하고
이 컴포넌트의 기능을
코드 작성 없이도 사용할 수 있습니다