이제 사용자가 저장한 장소들을 fetch하는 부분은
잘 작동하고 있습니다
AvailablePlaces를 fetch하는 것과 마찬가지입니다
이 앱 컴포넌트가 처음 렌더링되고 나서
바로 해야 합니다
그리고 무한 루프를 방지하기 위해서는
상태를 업데이트할 때
useEffect를 사용해야 합니다
그래서 그 장소들을 fetch하기 위해
http.js로 넘어가보겠습니다
그리고 거기서
fetchAvailablePlaces 함수를 복사하는 걸로 시작해 보겠습니다
그리고 그 복사본의 이름을 fetchUserPlaces라고 바꿔줍니다
왜냐하면 로직은 거의 똑같기 떄문입니다
하지만 결국은 여기서 user-places로 요청을 보내야 합니다
그리고 user places를 fetch하는데 실패한
에러 메시지를 수정할 수 있습니다
그것 말고는 이 함수는 이대로 두고
앱 파일(App.jsx)로 돌아가보겠습니다
그리고 여기에는 전에 말했듯이, useEffect의 도움을 받아
place를 fetch해야 합니다
그건 리액트에서 가져와야 하고
가져온 후에 Effect 함수를 정의하고
이 의존성 배열도 정의해줍니다
그리고 Effect 함수 안에 비동기 함수를 추가해서
이름은 fetchPlaces라 짓고 그걸로 비동기 await를 사용할 수 있습니다
그 다음엔 이 함수를 바로 실행해야 합니다
전에 availablePlaces에서 했던 것과 마찬가지입니다
거기서도 헬퍼(helper) 함수를 정의했었습니다
그럼 이제 앱 파일의 fetchPlaces 헬퍼 함수 안에서
await하며 fetchUserPlaces를 불러올 수 있습니다
이 http.js에서 복사하고 수정한 이 함수 또한
가져와야 합니다
이게 우리에게 user places를 넘겨줄 것이고
아니면 그냥 places로 이름을 지으셔도 됩니다
그리고 물론 그 데이터로 이런 식으로
user places를 set할 수 있습니다
하지만 물론 fethch 작업이 잘못될 수도 있습니다
하지만 전에 했던 것처럼, 이걸 try catch로 감싸줘야 합니다
그리고 여기서는
loading 상태를 관리하고 싶은데, 이유는 당연히
처음엔 아무 places도 없고 저는 웹사이트 방문자와
소통하여 현재 places를 fetch하고 있다고
알려주면서 더 나은 사용자 경험을 주기 위함입니다
그래서 또 전에 그랬던 것처럼, availablePlaces.jsx 파일에서
이제 fetching과 error 상태를 추가해줘야 합니다
그래서 이 상태들을
availablePlaces에서 app.jsx로 복사해주겠습니다
그리고 이 availablePlaces는 없애주겠습니다
그건 여기서 필요 없고
다른 두 상태만 필요한데, 그것과 함께 data 상태와
user places 상태도 데이터를 받은 후 설정해줍니다
그럼 이제 fetchPlaces 안에서
fetching을 True로 설정해주는 걸로 시작해 봅시다
그리고 이 try catch 블록 다음에는 False를 해 줍니다
그리고 이건 try catch 후에 한 번만 해야 합니다
다른 중첩 코드가 없기 때문입니다
그래서 전처럼 AvailablePlaces와 getCurrentPosition를 사용해
독립적으로 실행되지 않을 겁니다
그게 여기 없기 때문에 try-catch 이후에
한 번의 False 호출이면 충분합니다
이제 이 catch 블록에서 setError를 부르고
그걸 객체로 설정해주고
message 속성을 넣어줍니다
error.message나 대체 속성으로 설정해주면 됩니다
'사용자 장소를 불러오는데 실패했습니다'로 하겠습니다
그럼 이제 모든 상태를 사용할 수 있습니다
user places 상태는 이미 JSX 코드에서
사용되고 있습니다
이 places 컴포넌트로 전달되지만
이제 loadingText와 isLoading 프롬프트도
places로 전달해줍니다
이전에 AvailablePlaces 컴포넌트에 했던 것처럼요
isLoading이 isFetching의 값을 받아야 합니다
True인지 False인지는 요청이
오고 있는지에 따라 달렸습니다
그리고 loadingText가 로딩 메시지를
'장소를 불러오는 중입니다'와 같이 띄워줍니다
이제 뭔가 잘못되면, 에러를 나타내고 싶습니다
그래서 이 error 상태에 기반해
조건적으로 출력해줄 겁니다
error 컴포넌트에 title을
'에러가 발생했습니다'로 설정해주고 메시지를 error 객체에 전달합니다
아니면 거기서 에러 메시지로 전달한다는 표현이 더 정확합니다
places는 에러가 없을 때만 렌더링되어야 합니다
그러니 !error일 경우로 확인을 해주고 여기서
그럴 경우 places를 렌더링하게 합니다
그럼 저장하고 새로고침을 하면
백엔드에서 데이터들을 fetch하고 있는데
그걸 확인하려면 로딩 메시지를 확인해볼 수 있습니다
다시 네트워크를 슬로우3G로 스로틀링해주고
새로고침을 해서 기다려 줍니다
하지만 페이지가 로딩되면, 보이는 건
저 첫 번째 상자 안에 로딩 문구도 보여야 합니다
여기서 '데이터를 불러오는 중입니다'가 보이고
그러다가 장소 데이터가 도착합니다
그러니 잘 작동한다는 뜻입니다
이제 뭔가 문제가 발생하면, 예를 들어 제가
또 s를 URL에 추가해서 문제를 만들어 보겠습니다
그러면 이 에러 메시지 띄워집니다
그러니 에러를 다루는 것도 잘 작동합니다
그럼 이제 다 지워보겠습니다
이게 완료된 앱입니다
availablePlaces를 로딩할 수 있고
그 장소들을 추가하고 저장할 수도 있고
재로딩해서 그 저장된 장소들을 다시 fetch해 올 수도 있고
업데이트하고 싶다면 업데이트하고
하고 싶지 않으면 하지 않고, 이런 것들이 다 잘 작동하고 있습니다
그 데이터들을 저장할 수 있는 분리된 백엔드를 사용해서 가능합니다
그리고 분리된 백엔드의 장점은
이제 이것을 전 세계에 있는 사용자들이
사용할 수 있다는 것입니다
데이터는 더이상 리액트 앱 내 로컬에 저장되지 않고
이제 더 강력하고 다재다능한
리액트 앱을 구축할 수 있습니다