이렇게 커스텀 훅을 사용하여
장소를 가져오는 데 성공했습니다
그런데 하나가 빠져 있거나 삭제해야 하는 상황에
이 때 우리는 컴포넌트를 수정할 수 있습니다
이 컴포넌트에는 handleSelectPlace와
handleRemovePlace 함수가 있습니다
이 두 함수는 useFetch를 사용하여
만들어진 상태값을 수정할 수 있어야 합니다
하지만 현재로서는 이 컴포넌트들이 의도한 대로 작동하지 않고 있습니다
지금 상태값을 업데이트하려고 하는데
여기서는 당연히 업데이트할 수 없습니다
상태값은 이제 useFetch에서 관리되기 때문입니다
업데이트하려는 userPlaces 상태는 useFetch에서 관리되고 있습니다
이 문제를 해결할 수 있는 방법을 생각해 봅시다
해결책은 생각보다 간단명료합니다
우리가 만든 커스텀 훅에서
상태값만 노출할 수 있는 것이 아닙니다
상태 업데이트 함수나 해당 함수를 포함하는
커스텀 함수들도 노출할 수 있습니다
여기서는 간단하게 setFetchedData를 노출할 겁니다
그래서 우리가 여기서 값을 반환할 때
setFetchedData로 포인터(pointer)를 반환할 수 있습니다
다시 앱 파일(App.jsx)로 돌아와서
여기서 setFetchedData를 추출할 수 있고
원한다면 그 함수에 별칭를 배정할 수도 있습니다
예를 들어, 이미 사용했던 이름인
setUserPlaces를 입력해 봅시다
이렇게 해서 우리는 커스텀 훅에 있는
이 상태값을 수정할 수 있게 됩니다
수정 가능 범위를 제한하고 싶다면
이 state updating 함수에 커스텀 함수를 추가하여
업데이트가 진행되기 전에 추가로
확인을 받을 수 있도록 설정할 수 있습니다
여기서는 굳이 필요하지 않은 과정입니다
이 useFetch 훅을 다른 컴포넌트에서 사용하면
어떤 효과가 있을지 궁금해하는 분들이 있을 것입니다
우리가 이 훅을 다른 컴포넌트에도 사용하고
앱 컴포넌트에서 상태값을 업데이트하면
다른 컴포넌트에도 영향을 미칠지
궁금하실 수 있습니다
정답은 '영향을 주지 않는다' 입니다
컴포넌트를 사용할 때와 마찬가지로
커스텀 훅을 사용할 때는
한 번 사용할 때마다 새로운 복사본이 독립적으로 만들어집니다
즉 제가 앱 컴포넌트에서 useFetch를 사용하면
useFetch에서 관리되는 여기서 새로 만들어진 상태값은
컴포넌트와만 연결됩니다앱
그리고 useFetch를 다른 컴포넌트에서 사용하게 되면
같은 상태값이 새로 만들어지는 것입니다
그리고 이것은 해당 컴포넌트에만 적용되는 독립적인 상태 스냅샷(snapshot)입니다
그렇다면, useState를 여러 컴포넌트에서 사용할 때
각각 전부 독립적인 상태 스냅샷으로 사용할 수 있는 것처럼
똑같은 원리로
상태값을 사용하고 있는 커스텀 훅을 사용할 수 있을까요?
이 훅을 사용하는 모든 컴포넌트는
각각 독립적인 상태 스냅샷을 부여받습니다
따라서 하나의 컴포넌트에서 상태값을 바꾼다고 해서
다른 컴포넌트의 상태값들이 바뀌는 것은 아닙니다
아무리 같은 커스텀 훅을 사용한다고 할지라도 말입니다
handleRemovePlace와 handleSelectPlace를
작동시키는 속성을 다시 추가할 수도 있습니다
그리고 여기 뜨는 경고문에
setUserPlaces가 여기 useCallback 호출에
의존성(dependency)으로 추가되어야 한다고 나와 있습니다
이 useCallback 호출의 의존성 배열입니다
이 작업은 커스텀 훅을 사용하지 않을 때는 할 필요가 없었습니다
그 이유는 일반적으로 상태 업데이트 함수가
useCallback이나 useEffect의 의존성 배열로 추가될 필요가 없었기 때문입니다
리액트는 모든 상태 업데이트 함수가
절대 변하지 않을 것임을 보장합니다
하지만 지금 이 프로젝트는 setUserPlaces가
결국 상태 업데이트 함수를 의미한다는 사실을 인지하지 못하고 있습니다
그 이유는 여기서 보이는 것은
우리가 어떤 객체에서 속성을 끌어낸다는 수식뿐이기 때문입니다
따라서 완성도를 높이고
저 경고를 없애기 위해서 여기에 setUserPlaces를 추가하겠습니다
굳이 짚자면 아무런 변화도 생기지는 않습니다
왜냐하면 setUserPlaces는 상태 업데이트 함수를 의미하고
리액트는 상태 업데이트 함수가 절대 변하지 않음을 보장하기 때문입니다
하지만 경고문을 없애기 위해 이 작업을 해주겠습니다
그렇게 해서 이 커스텀 훅을 여기서 사용하게 되었고
결과적으로 장소를 업데이트할 수 있게 되었습니다
그렇다면 앱 파일(App.jsx)에서 useEffect import를 제거할 수 있고
모든 파일을 저장하겠습니다
그리고 새로고침을 누르면
추가한 장소가 보이게 됩니다
다시 새로 고쳐도 여전히 보입니다
그리고 콘솔에는 어떠한 오류도 없습니다
이렇게 장소 하나를 삭제하면
이렇게 아무런 오류 없이 삭제된 것이 보입니다
새로 고쳐도 여전히 오류가 없습니다
이렇게 모두 정상적으로 작동하는 것은
커스텀 훅을 잘 활용했기 때문입니다