모인 웹에서는 특정 국가가 갑자기 송금이 불가능한 상태가 되거나, 송금액이 제한되는 경우가 종종 있었다.
그럴 때마다 client 에서 일일히 하드코딩으로 송금을 보내지 못하도록 제한하는 식으로 처리했다.
이렇게 되면 특정 국가가 송금 불가능이 될 때마다 한두줄 수정해서 배포까지 나가야 하기 때문에 비효율이 발생한다.
때문에 처음 웹을 실행했을 때 서버로 부터 각 국가들에 대해서 송금 가능여부 대해 받아와서 받아온 정보를 토대로 송금신청하기 버튼의 disabled 상태를 관리하려고 했다.
이를 위해 legacy code 를 확인해 보니 보내는 금액, 받는금액, 받는 국가 설정에 관련된 계산을 한 Component 상태관리를 하고 있었다.
그래서 국가별 송금가능 정보를 받아오는 것을 customhook 으로 만들고 해당 customhook 을 위의 Component 에서 호출하는 것으로 구성했다.
custom hook 은 대략 아래처럼 구성했다.
const useFetchData = (url) => {
const dispatch = useDispatch();
const [isLoading, setIsLoading] = useState(false);
const [apiData, setApiData] = useState(null);
const [serverError, setServerError] = useState(null);
useEffect(() => {
setIsLoading(true);
const fetchData = async () => {
try {
dispatch(fetchApiData());
const resp = await axios.get(url);
const data = await resp?.data;
dispatch(fetchApiSuccess(data));
setApiData(data);
setIsLoading(false);
} catch (error) {
setServerError(error);
dispatch(fetchApiFailure());
setIsLoading(false);
}
};
fetchData();
}, [dispatch, url]);
return { isLoading, apiData, serverError };
};
만든 customhook 을 송금액 정보를 관리하는 Component 에서 호출하여
받은 데이터를 가지고 송금가능여부를 계산하여 버튼 disabled 를 관리하려 했지만 제대로 작동하지 않았다.
분명 서버에서 받은 데이터로는 송금이 가능해야해서 버튼이 활성화 되어야 하는데 비활성화인 상태로 있었다.
알고보니 customhook 호출 위치 문제 였다.
customhook 은 사실 상태관련 로직을 분리한 것 뿐이지 아얘 다른 컴포넌트에서 호출하는 것이 아니었다.
때문에 customhook 을 호출하는 컴포넌트의 상태가 변할 때 마다 customhook 이 호출되게 된다.
원했던 것은 컴포넌트 mount 될 때 데이터를 한번만 가져와서 가져온 데이터를 가지고 사용하는 것인데,
customhook 을 호출하는 컴포넌트가 mount 되었을 때 위의 customhook 의 경우 서버로 부터 데이터를 받아서 상태를 update 한뒤 정상적으로 상태를 리턴하지만 이후 component 에서 다시 상태를 update 하게 되면 상태가 초기화 되게 되어 서버로 부터 받은 데이터가 초기화 되게 된다.
때문에 서버로 부터 받은 데이터를 사용할 수 없게 된다.
이를 방지하기 위해서는 useEffect 에 배열에 상태를 할당해주면 되기는 하나
내가 원했던 것은 mount 될 때 한번만 받아오는 것이기 때문에
중 하나를 선택해야 했다.
방법 1의 경우 legacy code 의 수정이 많이 필요해서 사용하지 않고 방법2를 선택하여 해결했다.