이제 그 availablePlaces를 가져오는 것이
제일 먼저 해야할 일입니다
그리고 이 장소들을 클릭할 수 있고
고른 장소에 추가할 수 있어야 합니다
그러려면
백엔드로 요청을 보낼 수도 있어야 합니다
그래야 고른 것들이 여기 저장됩니다
지금은 앱을 다시 로딩해보면
골랐던 내역이 사라집니다
그렇기 때문에
저장 내역을 백엔드로부터
가져와 보겠습니다
그리고 그렇게 하면
이 임시 백엔드에서 endpoint로 가는 두 가지 경로가 있어서
우리가 고른 장소들을 저장하고
그 장소들을 받아올 수 있게 합니다
전에 설명했던 것처럼, 이 임시 앱에는
장소들이이
이 웹 앱을 사용하는 사용자들과 전부 공유됩니다
그러니 모두가 같은 선택지를 공유하게 됩니다
하지만 이 데모 버전에서는
그렇게 해도 문제가 없습니다
그래서 일단 시작해보겠습니다
장소를 고르면
그 업데이트된 장소 선택지를
백엔드로 보내겠습니다
그러려면 앱 파일(App.jsx)로 가야 합니다
왜냐하면 여기서 userPlaces를 출력할 수 있고
여기에 userPlaces state가 있기 때문입니다
userPlaces 상태는 장소를 고를 때마다 업데이트되는
장소 배열입니다
그래서 이제 이 handleSelectPlace 안에
그냥 이 상태를 업데이트하지 않고
업데이트된 장소 배열을
백엔드로 보내겠습니다
그러기 위해서 여기에 코드를 몇 가지 추가해야 합니다
그 전에 상태를 업데이트하고
아니면 여기 상태를 업데이트하기 전에 추가해도 됩니다
어떤 위치가 어떤 이유에 따라 좋은지는
나중에 다시 설명해드리겠습니다
이제 요청을 보내는 것으로 시작을 해보겠습니다
그 전에 상태 업데이트를 햊 ㅜ셔야 합니다
그러기 위해서는 다시 fetch 함수를 사용합니다
왜냐하면 전에 설명했듯이
이 함수는 요청을 보내는 데에도 사용되기 때문입니다
즉 데이터를 받아오는 것 뿐만 아니라 바꿀 수도 있습니다
물론 이름만 봐서는
데이터를 가져오기만 할 것 같지만 그렇지 않습니다
하지만 여기 fetch 코드나 보내는 코드를 쓰진 않을 겁니다
하지만 대신 이 http.js 파일을 사용해서
이 파일에 새로운 함수를 추가해보겠습니다
새롭게 내보낸 이 비동기 함수가
사용자 장소를 업데이트하는 역할을 할 겁니다
그러니 이름을 updateUserPlaces라고 지어주겠습니다
이런 식으로 하겠습니다
그리고 여기서, places 배열을 예상합니다
그리고 그게 백엔드로 보내져야 합니다
왜냐하면 이 임시 백엔드 API와
이 임시 백엔드 서버는 places 배열을 받기를 기다리고
그쪽 파일에 저장하기 때문입니다
그래서 여기서 꼭
places 배열을 보내도록 해야 합니다
말했듯이, 이건 fetch 함수를 사용하면 됩니다
그리고 여기서, 또, 요청을 보내야 하는
URL을 지정해야 합니다
여기 보면, localhost3000이고
그 다음 user-places 입니다
이게 제가 제공한 이 임시 백엔드가
목표로 해야 할 경로입니다
하지만 이제 이런 식으로 요청을 보내는 건
충분하지 않습니다
대신 여기서 그 places를 바꾸기 위해
백엔드로부터 put 요청이 요구됩니다
그러니 사용된 HTTP 메소드를 바꿔야 합니다
왜냐하면 기본적으로 이 get 메소드인데
그건 여기서 잘못된 메소드이기 때문입니다
이거는 두 번째 인수의 도움을 받아
fetch로 전달할 수 있습니다
두 번째 인수는 나가는 요청들을 설정하는
설정 함수입니다
예를 들어 여기에 메소드 속성을 설정하고
정의하여 HTTP 요청 메소드를 보내겠습니다
이 경우, 예를 들어, PUT 입니다
그리고 body 속성을 꼭 추가해서
어떤 데이터가 요청 body에 첨부되어야 하는지 정의합니다
즉 나가는 요청 body에 대한 내용입니다
그리고 여기 이게 places 배열이어야 합니다
그래서 그 데이터는 꼭
첨부될 수 있는 형식이어야 하는데
자바의 배열은 첨부할 수 있는 형식이 아닙니다
그래서 이건 JSON 형식으로 변환되어야 합니다
전에도 설명드렸던 내용입니다
그래서 여기서 JSON.stringify(places)를 불러줍니다
이게 places 배열을 JSON 형식으로 변환해주면
이제 이건 첨부될 수 있습니다
마지막으로 중요한 건, 헤더가 더 추가되어야 하는데
바로 요청에 첨부될 추가 메타데이터입니다
여기서는 특정하게
Content-type 헤더를 추가하고
application/json에 정의해서 백엔드에
이 요청에 첨부될 데이터가 JSON 형식이라고
알려줘야 합니다
이 과정이 꼭 필요한 이유가
그래야 데이터가 성공적으로 백엔드에 추출되기 때문입니다
그 다음 결과를 await 해주고
응답을 받겠습니다
그리고 전처럼
그 응답을 살펴보고 분석하는 과정을 반복합니다
예를 들어 여기서 response.json을 부르고 await함으로써
응답 데이터를 받을 수 있습니다
그리고 응답에 문제가 있는지도 확인해 보겠습니다
만약 에러 코드를 받았다면
이런 경우 다시 새로운 에러를 throw 합니다
'사용자 데이터 업데이트에 실패했습니다'로 하겠습니다
그리고 마지막에 응답 데이터(resData)를 반환하면
여기에 message 속성이 붙습니다
왜냐하면 이 백엔드 API를 살펴보면
put user-places 루트에서
응답으로 받은 객체에
message 속성이 포함되어 있기 때문입니다
하지만 이 앱에서는
그 데이터를 사용하지는 않겠습니다만
일단 여기에 반환하겠습니다
그렇게 updateUserPlaces 함수를 여기에 만들었습니다
app.jsx 파일에도 있습니다
그럼 이제 상태를 업데이트 한 후 이 함수를 사용할 수 있습니다
이 handleSelectPlaces 안에서 이루어져야 겠죠
그 다음 updateUserPlaces 불러야 하는데
물론 http.js 파일에서 가져오겠습니다
그리고 이 밑에서 제가 부를 때
업데이트된 places도 전달합니다
그러면 여러분들이
userPlaces를 사용하면 될 것이라고 생각하실 수 있습니다
이 상태를 방금 업데이트했기 때문입니다
이 단계 바로 이전이었습니다
하지만 전에 배웠다시피
상태 업데이트는 즉각적으로
이 코드 다음 줄에서 바로 이루어지지 않습니다
그 대신
다음 번 컴포넌트 함수가 실행되고 나서 이루어집니다
그건 이 상태 업데이트가 실행 일정을 조정하는 것입니다
하지만 그 전에도 이 코드는 실행이 될 겁니다
왜냐하면 이전 컴포넌트의 일부이기 때문입니다
그러니까, 업데이트되기 전 컴포넌트입니다
그러니 이전 상태를 사용하는 건 작동되지 않습니다
그래서 여기서 우리가 해야될 것은
이전 상태를 사용하고 이전 userPlaces를
이 새 배열에 추출하는 것입니다
그 다음 여기서 상태를 업데이트하면서
새로운 selectedPlace를 추가해줍니다
이전 userPlaces 앞에 추가해줍니다
그리고 그게 업데이트된 데이터 배열을
백엔드로 보낼 겁니다
이제 물론 이 동작은 시간이 좀 걸립니다
그러므로 다음 단계로 넘어가기 전에 이걸
await 해주겠습니다
하지만 await는 비동기를 사용한
함수 내에서만 동작합니다
그리고 좋은 점은 이 함수가
쉽게 비동기를 사용할 수 있다는 것입니다
이 함수 작업은 결국
이벤트 처리(event listener) 함수로 만들어주는 것이기 때문입니다
그리고 장소를 고를 때 실행됩니다
그리고 거기에 비동기 함수를 쓴다고 해서 문제될 게 없습니다
전처럼 잘 동작할 겁니다
하지만 이제 여기서도 await를 사용할 수 있습니다
그리고 async await를 사용할 땐
try catch로 이 코드를 감쌀 수 있습니다
그리고 물론 에러를 catch하는 데 실패할 수도 있기 때문에
이게 실패할 경우 실행되어야 할
코드를 작성해야 합니다
하지만 아직은 이것까지 신경쓰진 않겠습니다
일단 이렇게 요청을 보내 보겠습니다
기억하셔야 할 게, 지금은
로딩 상태도 관리되고 있지 않습니다
대신, 일단 저장을 해보고
앱으로 돌아가서
개발자 도구를 열어서 발생 가능한 에러들을 확인합니다
여기 로그, 즉 기록이 많이 보이는데 그 이유는
우리가 지나는 각 상태들 때문입니다
예를 들어 데이터를 가져올 때나 로딩할 때입니다
그리고 이 앱은 엄격 모드(strict mode)를 사용하기 때문에
컴포넌트 함수가
데이터를 가져올 때, 꽤 자주 실행됩니다
하지만 결국 데이터를 받긴 합니다
그리고 이제 여기서 장소를 고르면, 두 가지가 보입니다
하나는, 그게 즉시 여기 추가되었다는 겁니다
하지만 여기 에러가 난 것도 보이실 것입니다
연결 거부 에러입니다
백엔드가 실행 중인 터미널을 열어보면
충돌된 것을 볼 수 있습니다
받은 데이터가
마음에 들지 않았나 봅니다
그래서 이 과정을 다시 시작해야 하는데
다시 코드샌드박스의 node app.js를 실행해서 시작해줍니다
충돌이 났을 때 간단하게 코드샌드박스에서
재시작해주거나 거기서 새로고침을 해 주면 됩니다
그러면 잘 작동할 겁니다
그리고 이 에러를 고치기 위해서,
https.js 파일로 돌아가서 실수를 하나 수정하겠습니다
PUT 요청과 함께 보내지는 데이터는
이런 식으로 places 배열이어서는 안 됩니다
백엔드가 예상하는 건 places 키를 가진
객체입니다
그 다음 이 배열을 포함할 겁니다
그래서 그 배열을 감쌀 객체가 필요합니다
이게 굉장히 중요한 게, 이 예시로
백엔드가 특정 종류의 요청과 정확히 원하는 데이터만
받는다는 것을 알 수 있습니다
그래서 다시 http.js를 보면
이걸 중괄호로 감싸주고 places 키를 추가해야 합니다
그리고 places를 키 값으로 전달합니다
그리고 키와 값을 가진 변수가 동일한 이름을 갖고 있기 때문에
이렇게 더 간단한 방법을 사용할 수 있습니다
바로 이 줄인 표기법입니다
그러면 저장하고 새로고침을 해 보겠습니다
그러면 다시 장소들을 fetch해야 합니다
그래서 하나를 골라보니, 결과가 더 좋아보입니다
에러가 없습니다
이제 다시 백엔드로 가서
데이터 폴더를 보면
user-places.json 파일 안에
새로운 정보가 있습니다
바로 데이터가 있는데
이게 우리가 보낸 장소 정보입니다
잘 작동하는 것 같습니다